Skip to content

Instantly share code, notes, and snippets.

@GalindoSVQ
Created January 11, 2024 21:26
Show Gist options
  • Save GalindoSVQ/07cbc6330876c8aa941c0da3b293d83a to your computer and use it in GitHub Desktop.
Save GalindoSVQ/07cbc6330876c8aa941c0da3b293d83a to your computer and use it in GitHub Desktop.
import * as React from "react";
const dispatchStorageEvent = (key, newValue) => {
window.dispatchEvent(new StorageEvent("storage", { key, newValue }));
};
const setItem = (key, value) => {
const stringifiedValue = JSON.stringify(value);
window.localStorage.setItem(key, stringifiedValue);
dispatchStorageEvent(key, stringifiedValue);
};
const removeItem = (key) => {
window.localStorage.removeItem(key);
dispatchStorageEvent(key, null);
};
const getItem = (key) => {
return window.localStorage.getItem(key);
};
const subscribe = (callback) => {
window.addEventListener("storage", callback);
return () => window.removeEventListener("storage", callback);
};
const getServerSnapshot = () => {
throw Error("useLocalStorage is a client-only hook");
};
export default function useLocalStorage(key, initialValue) {
const getSnapshot = () => getItem(key);
const store = React.useSyncExternalStore(
subscribe,
getSnapshot,
getServerSnapshot
);
const setState = React.useCallback(
(v) => {
try {
const nextState = typeof v === "function" ? v(JSON.parse(store)) : v;
if (nextState === undefined || nextState === null) {
removeItem(key);
} else {
setItem(key, nextState);
}
} catch (e) {
console.warn(e);
}
},
[key, store]
);
React.useEffect(() => {
if (getItem(key) === null && typeof initialValue !== "undefined") {
setItem(key, initialValue);
}
}, [key, initialValue]);
return [store ? JSON.parse(store) : initialValue, setState];
}
@GalindoSVQ
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment