From bfdb8b9bcfeef851fff6ac9553e159798940a8b7 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 7 Nov 2023 21:54:28 +0800 Subject: [PATCH] fix(use-local-storage): fix impl --- src/use-local-storage/index.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/use-local-storage/index.ts b/src/use-local-storage/index.ts index 8515ce81..5bb56a62 100644 --- a/src/use-local-storage/index.ts +++ b/src/use-local-storage/index.ts @@ -38,7 +38,11 @@ const removeLocalStorageItem = (key: string) => { const getLocalStorageItem = (key: string) => { if (typeof window !== 'undefined') { try { - return window.localStorage.getItem(key); + const value = window.localStorage.getItem(key); + if (value) { + return JSON.parse(value); + } + return value; } catch (e) { console.warn(e); return null; @@ -62,13 +66,13 @@ const getServerSnapshotWithoutServerValue = () => noSSR('foxact: useLocalStorage const isFunction = (x: unknown): x is Function => typeof x === 'function'; /** @see https://foxact.skk.moe/use-local-storage */ -export const useLocalStorage = (key: string, serverValue?: T) => { - const getSnapshot = () => getLocalStorageItem(key); +export function useLocalStorage(key: string, serverValue?: T) { + const getSnapshot = () => getLocalStorageItem(key) as T | null; // If the serverValue is provided, we pass it to useSES' getServerSnapshot, which will be used during SSR // If the serverValue is not provided, we don't pass it to useSES, which will cause useSES to opt-in client-side rendering const getServerSnapshot = typeof serverValue !== 'undefined' - ? () => JSON.stringify(serverValue) + ? () => serverValue : getServerSnapshotWithoutServerValue; const store = useSyncExternalStore( @@ -77,14 +81,14 @@ export const useLocalStorage = (key: string, serverVa getServerSnapshot ); - const setState = useCallback>>( + const setState = useCallback>>( (v) => { try { const nextState = isFunction(v) - ? v(store != null ? JSON.parse(store) : null) + ? v(store ?? null) : v; - if (nextState === undefined || nextState === null) { + if (nextState == null) { removeLocalStorageItem(key); } else { setLocalStorageItem(key, nextState); @@ -105,5 +109,5 @@ export const useLocalStorage = (key: string, serverVa } }, [key, serverValue]); - return [store != null ? JSON.parse(store) : serverValue, setState]; -}; + return [store ?? serverValue ?? null, setState] as const; +}