diff --git a/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.demo.tsx b/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.demo.tsx index 8de58dd7..8565f777 100644 --- a/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.demo.tsx +++ b/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.demo.tsx @@ -1,7 +1,7 @@ import { useLocalStorage } from './useLocalStorage' export default function Component() { - const [value, setValue] = useLocalStorage('test-key', 0) + const [value, setValue, reset] = useLocalStorage('test-key', 0) return (
@@ -20,6 +20,13 @@ export default function Component() { > Decrement +
) } diff --git a/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.test.ts b/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.test.ts index aa9cedf7..f92e41dd 100644 --- a/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.test.ts +++ b/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.test.ts @@ -128,6 +128,49 @@ describe('useLocalStorage()', () => { expect(window.localStorage.getItem('count')).toEqual('5') }) + it('Reset the state with static initial value', () => { + const { result } = renderHook(() => useLocalStorage('count', 2)) + + act(() => { + const setState = result.current[1] + const reset = result.current[2] + setState(prev => prev + 1) + setState(prev => prev + 1) + setState(prev => prev + 1) + reset() + }) + + expect(result.current[0]).toBe(2) + expect(window.localStorage.getItem('count')).toEqual('2') + }) + + it('Reset the state with initial value as a function', () => { + const { result } = renderHook(() => + useLocalStorage('count', () => ({ + id: 1, + name: 'Joe', + })), + ) + + act(() => { + const setState = result.current[1] + const reset = result.current[2] + setState({ + id: 2, + name: 'Jane', + }) + reset() + }) + + expect(result.current[0]).toEqual({ + id: 1, + name: 'Joe', + }) + expect(window.localStorage.getItem('count')).toEqual( + '{"id":1,"name":"Joe"}', + ) + }) + it('[Event] Update one hook updates the others', () => { const initialValues: [string, unknown] = ['key', 'initial'] const { result: A } = renderHook(() => useLocalStorage(...initialValues)) diff --git a/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.ts b/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.ts index f8d2daed..08955a91 100644 --- a/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.ts +++ b/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.ts @@ -28,7 +28,7 @@ const IS_SERVER = typeof window === 'undefined' * @param {?boolean} [options.initializeWithValue] - If `true` (default), the hook will initialize reading the local storage. In SSR, you should set it to `false`, returning the initial value initially. * @param {?((value: T) => string)} [options.serializer] - A function to serialize the value before storing it. * @param {?((value: string) => T)} [options.deserializer] - A function to deserialize the stored value. - * @returns {[T, Dispatch>]} A tuple containing the stored value and a function to set the value. + * @returns {[T, Dispatch>, () => void]} A tuple containing the stored value and a function to set the value. * @see [Documentation](https://usehooks-ts.com/react-hook/use-local-storage) * @see [MDN Local Storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) * @example @@ -39,7 +39,7 @@ export function useLocalStorage( key: string, initialValue: T | (() => T), options: UseLocalStorageOptions = {}, -): [T, Dispatch>] { +): [T, Dispatch>, () => void] { const { initializeWithValue = true } = options const serializer = useCallback<(value: T) => string>( @@ -133,6 +133,17 @@ export function useLocalStorage( } }) + const resetValue = useCallback(() => { + try { + const initialValueToUse = + initialValue instanceof Function ? initialValue() : initialValue + + setValue(initialValueToUse) + } catch (error) { + console.warn(`Error resetting localStorage key “${key}”:`, error) + } + }, [initialValue, setValue, key]) + useEffect(() => { setStoredValue(readValue()) // eslint-disable-next-line react-hooks/exhaustive-deps @@ -155,5 +166,5 @@ export function useLocalStorage( // See: useLocalStorage() useEventListener('local-storage', handleStorageChange) - return [storedValue, setValue] + return [storedValue, setValue, resetValue] }