react icon indicating copy to clipboard operation
react copied to clipboard

Uncontrolled re-rendering with useEffect within custom hook when unmounting component and when prop to hook is an unanchored array

Open AnastasiusVivaldus opened this issue 3 years ago • 0 comments

I have a component called MyWillUnmount that uses a custom hook called useLocalStorage.

const emptyArray = [];
const MyWillUnmount = () => {
  const [] = useLocalStorage('KEY',[]);
  ...
}

export function useLocalStorage<T>(key: TLocalStorageKeys, initValue: any): [T, (value: any) => void] {
  const [storedValue, setStoredValue] = useState<T>(initValue);
  useEffect(() => {
    setStoredValue(
      (() => {
        try {
          const item = window.localStorage.getItem(key);
          return item ? JSON.parse(item) : initValue;
        } catch (error) {
          console.log(error);
          return initValue;
        }
      })()
    );
  }, [key, initValue]);
  ...
}

When this component unmounts, the useEffect within useLocalStorage undergoes rapid re-triggering; it seems to think that the initValue prop, which is set to [], is rapidly varying. However, if I replace [] with emptyArray, then it does not get rapidly re-triggered. This problem also occurs if the initial value is set to {}, but does not happen if it is a string, number or boolean. I'm guessing that the undesirable retriggering has something to do with a sudden loss of closure.

AnastasiusVivaldus avatar Jul 29 '22 14:07 AnastasiusVivaldus