From f6dfef700428a69b549cc0a8ec0851a6a789a4db Mon Sep 17 00:00:00 2001 From: yixiaojiu <1918418506@qq.com> Date: Wed, 23 Aug 2023 19:12:50 +0800 Subject: [PATCH] feat: useLocalStorage setState support funtion --- packages/local-storage/src/__tests__/index.test.js | 10 ++++++++++ packages/local-storage/src/index.ts | 12 ++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/local-storage/src/__tests__/index.test.js b/packages/local-storage/src/__tests__/index.test.js index 0813ba6..130ee55 100644 --- a/packages/local-storage/src/__tests__/index.test.js +++ b/packages/local-storage/src/__tests__/index.test.js @@ -79,6 +79,16 @@ describe('with localStorage', () => { expect(result.current[0]).toBe('foo'); }); + test('set new value through function', () => { + const {result} = renderHook(() => useLocalStorage('foo', {bar: 1})); + act(() => result.current[1](value => { + const newValue = {...value}; + newValue.bar = 2; + return newValue; + })); + expect(result.current[0].bar).toBe(2); + }); + test('ignore session storage change', () => { const {result} = renderHook(() => useLocalStorage('foo', 'bar')); const event = new StorageEvent('storage', { diff --git a/packages/local-storage/src/index.ts b/packages/local-storage/src/index.ts index 9618df4..cb3d86d 100644 --- a/packages/local-storage/src/index.ts +++ b/packages/local-storage/src/index.ts @@ -14,15 +14,19 @@ function getStorage(key: string, initialValue: T): T { } } +const isFunction = (value: unknown): value is (...args: any) => any => + typeof value === 'function'; + export function useLocalStorage(key: string, initialValue: T): [T, (value: T) => void] { const [value, setValue] = useState(() => getStorage(key, initialValue)); const setStorageValue = useCallback( - (value: T) => { + (newValue: T | ((prevValue?: T) => T)) => { + const currentValue = isFunction(newValue) ? newValue(value) : newValue; // eslint-disable-next-line no-unused-expressions - window?.localStorage?.setItem(key, JSON.stringify(value)); - setValue(value); + window?.localStorage?.setItem(key, JSON.stringify(currentValue)); + setValue(currentValue); }, - [key] + [key, value] ); useEffect( () => {