Files
cinny/src/app/state/utils/atomWithLocalStorage.ts
T

52 lines
1.3 KiB
TypeScript
Raw Normal View History

2024-01-21 23:50:56 +11:00
import { atom } from 'jotai';
export const getLocalStorageItem = <T>(key: string, defaultValue: T): T => {
const item = localStorage.getItem(key);
if (item === null) return defaultValue;
if (item === 'undefined') return undefined as T;
try {
return JSON.parse(item) as T;
} catch {
return defaultValue;
}
};
export const setLocalStorageItem = <T>(key: string, value: T) => {
localStorage.setItem(key, JSON.stringify(value));
};
export type GetLocalStorageItem<T> = (key: string) => T;
export type SetLocalStorageItem<T> = (key: string, value: T) => void;
export const atomWithLocalStorage = <T>(
key: string,
getItem: GetLocalStorageItem<T>,
setItem: SetLocalStorageItem<T>
) => {
const value = getItem(key);
const baseAtom = atom<T>(value);
baseAtom.onMount = (setAtom) => {
const handleChange = (evt: StorageEvent) => {
if (evt.key !== key) return;
setAtom(getItem(key));
};
window.addEventListener('storage', handleChange);
return () => {
window.removeEventListener('storage', handleChange);
};
};
const localStorageAtom = atom<T, [T], undefined>(
(get) => get(baseAtom),
(get, set, newValue) => {
set(baseAtom, newValue);
setItem(key, newValue);
}
);
return localStorageAtom;
};