Skip to content

Instantly share code, notes, and snippets.

@troygoode
Forked from AlpacaGoesCrazy/useSafeState.js
Last active July 27, 2021 05:44
Show Gist options
  • Save troygoode/0702ebabcf3875793feffe9b65da651a to your computer and use it in GitHub Desktop.
Save troygoode/0702ebabcf3875793feffe9b65da651a to your computer and use it in GitHub Desktop.
Hook for react state which prevents updates on unmounted components (in TypeScript)
import { useEffect, useRef, useState, Dispatch, SetStateAction } from "react";
/* originally via:
https://gist.github.com/AlpacaGoesCrazy/25e3a15fcd4e57fb8ccd408d488554d7
*/
const useStateSafe = function<T>(initialValue: T): [T, Dispatch<SetStateAction<T>>] {
const isMounted = useRef(false); // useRef to memorize if the component is mounted between renders
const [state, setState] = useState<T>(initialValue);
useEffect(() => {
isMounted.current = true;
return () => {
isMounted.current = false;
};
});
const setStateSafe = (t: T | ((prev: T) => T)) => {
if (isMounted.current) {
// do not call setState if the component already unmounted
setState(t);
}
};
return [state, setStateSafe];
};
export default useStateSafe;
@gnoesiboe
Copy link

Hi! Thank you for the great gist above! Do you know if this hook actually fixes the memory leak mentioned in the warning generated by React? Or does it just make sure no (no longer needed) state is updated and no warning is shown?

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment