Skip to content

Instantly share code, notes, and snippets.

@Wigny
Last active September 28, 2025 05:05
Show Gist options
  • Select an option

  • Save Wigny/ddbbbf775f169172b11617908b1cf0d3 to your computer and use it in GitHub Desktop.

Select an option

Save Wigny/ddbbbf775f169172b11617908b1cf0d3 to your computer and use it in GitHub Desktop.
import { useCallback, useSyncExternalStore } from 'react';
export function useLocalStorage<T>(key: string): [T | null, (value: T | null) => void] {
const onValueChange = useCallback(
(callback: () => void) => {
const handler = (event: StorageEvent) => {
if (event.storageArea === window.localStorage && event.key === key) callback();
};
window.addEventListener('storage', handler);
return () => window.removeEventListener('storage', handler);
},
[key]
);
const getValue = useCallback((): T | null => {
const value = window.localStorage.getItem(key);
return value === null ? null : JSON.parse(value);
}, [key]);
const setValue = useCallback(
(value: T | null) => {
const newValue = JSON.stringify(value);
window.localStorage.setItem(key, newValue);
// dispatches a storage event for the current window
window.dispatchEvent(new StorageEvent('storage', { storageArea: window.localStorage, key, newValue }));
},
[key]
);
const value = useSyncExternalStore(onValueChange, getValue);
return [value, setValue];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment