Browse Source

Init value for useState hook calls once (#11802)

Signed-off-by: Smirnov Aleksey <aleksey.smirnov@sbermarket.ru>

Signed-off-by: Smirnov Aleksey <aleksey.smirnov@sbermarket.ru>
Co-authored-by: Smirnov Aleksey <aleksey.smirnov@sbermarket.ru>
pull/11808/head
Aleksey Smirnov 2 years ago committed by GitHub
parent
commit
84c6f0e584
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      web/ui/react-app/src/hooks/useLocalStorage.test.tsx
  2. 5
      web/ui/react-app/src/hooks/useLocalStorage.tsx

14
web/ui/react-app/src/hooks/useLocalStorage.test.tsx

@ -24,4 +24,18 @@ describe('useLocalStorage', () => {
expect(result.current[0]).toEqual(newValue);
expect(localStorage.getItem(key)).toEqual(JSON.stringify(newValue));
});
it('localStorage.getItem calls once', () => {
// do not prepare the initial state on every render except the first
const spyStorage = jest.spyOn(Storage.prototype, 'getItem') as jest.Mock;
const key = 'mystorage';
const initialState = { a: 1, b: 2 };
const { result } = renderHook(() => useLocalStorage(key, initialState));
const newValue = { a: 2, b: 5 };
act(() => {
result.current[1](newValue);
});
expect(spyStorage).toHaveBeenCalledTimes(1);
spyStorage.mockReset();
});
});

5
web/ui/react-app/src/hooks/useLocalStorage.tsx

@ -1,8 +1,9 @@
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
export function useLocalStorage<S>(localStorageKey: string, initialState: S): [S, Dispatch<SetStateAction<S>>] {
const localStorageState = JSON.parse(localStorage.getItem(localStorageKey) || JSON.stringify(initialState));
const [value, setValue] = useState(localStorageState);
const [value, setValue] = useState(() =>
JSON.parse(localStorage.getItem(localStorageKey) || JSON.stringify(initialState))
);
useEffect(() => {
const serializedState = JSON.stringify(value);

Loading…
Cancel
Save