Last active
December 29, 2023 00:21
-
-
Save ekrresa/6d155c2702e73a86ba38d82a75ca9aa3 to your computer and use it in GitHub Desktop.
Custom react hook to manage localStorage values. SSR safe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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