Skip to content

Instantly share code, notes, and snippets.

@ekrresa
Last active December 29, 2023 00:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ekrresa/6d155c2702e73a86ba38d82a75ca9aa3 to your computer and use it in GitHub Desktop.
Save ekrresa/6d155c2702e73a86ba38d82a75ca9aa3 to your computer and use it in GitHub Desktop.
Custom react hook to manage localStorage values. SSR safe
export function useLocalStorage<T>(key: string, initialValue: T) {
const [value, setValue] = React.useState<T | undefined>(() => initialValue);
// Gets initial value from localStorage if available
React.useLayoutEffect(() => {
let initialValue;
try {
const localStorageValue = localStorage.getItem(key);
initialValue =
localStorageValue !== null
? parseJSON(localStorageValue)
: initialValue;
setValue(initialValue);
} catch (error) {
setValue(initialValue);
}
}, [key]);
React.useEffect(() => {
const onStorage = (e: StorageEvent) => {
if (e.key === key) {
const newValue =
e.newValue !== null ? parseJSON(e.newValue) : undefined;
setValue(newValue);
}
};
window.addEventListener("storage", onStorage);
return () => {
window.removeEventListener("storage", onStorage);
};
}, [key]);
const set = React.useCallback(
(newValue: T) => {
try {
setValue(newValue);
if (typeof newValue === "undefined") {
localStorage.removeItem(key);
} else {
localStorage.setItem(key, JSON.stringify(newValue));
}
} catch (error) {
}
},
[key]
);
const remove = React.useCallback(() => {
try {
setValue(undefined);
localStorage.removeItem(key);
} catch (error) {
}
}, [key]);
return [value, set, remove] as const;
}
function parseJSON(value: string) {
return value === "undefined" ? undefined : JSON.parse(value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment