Skip to content

Commit fdd1b23

Browse files
committed
fix(useLocalStorage): reinitialize on key change
1 parent a91c1f1 commit fdd1b23

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

src/useLocalStorage.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Dispatch, SetStateAction, useCallback, useState } from 'react';
1+
import { Dispatch, SetStateAction, useCallback, useState, useRef, useLayoutEffect } from 'react';
22
import { isBrowser, noop } from './misc/util';
33

44
type parserOptions<T> =
@@ -30,7 +30,7 @@ const useLocalStorage = <T>(
3030
: JSON.parse;
3131

3232
// eslint-disable-next-line react-hooks/rules-of-hooks
33-
const [state, setState] = useState<T | undefined>(() => {
33+
const initializer = useRef((key: string) => {
3434
try {
3535
const serializer = options ? (options.raw ? String : options.serializer) : JSON.stringify;
3636

@@ -49,6 +49,12 @@ const useLocalStorage = <T>(
4949
}
5050
});
5151

52+
// eslint-disable-next-line react-hooks/rules-of-hooks
53+
const [state, setState] = useState<T | undefined>(() => initializer.current(key));
54+
55+
// eslint-disable-next-line react-hooks/rules-of-hooks
56+
useLayoutEffect(() => setState(initializer.current(key)), [key]);
57+
5258
// eslint-disable-next-line react-hooks/rules-of-hooks
5359
const set: Dispatch<SetStateAction<T | undefined>> = useCallback(
5460
(valOrFunc) => {

tests/useLocalStorage.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ describe(useLocalStorage, () => {
8080
expect(foo).toEqual('baz');
8181
});
8282

83+
it('reinitializes state when key changes', () => {
84+
let key = 'foo';
85+
const { result, rerender } = renderHook(() => useLocalStorage(key, 'bar'));
86+
87+
const [, setState] = result.current;
88+
act(() => setState('baz'));
89+
key = 'bar';
90+
rerender();
91+
92+
const [state] = result.current;
93+
expect(state).toEqual('bar');
94+
});
95+
8396
/*
8497
it('keeps multiple hooks accessing the same key in sync', () => {
8598
localStorage.setItem('foo', 'bar');

0 commit comments

Comments
 (0)