import { Dispatch, SetStateAction, useCallback, useEffect, useRef, useState } from 'react'; // useState can cause memory leaks if it is set after the component unmounted. For example, if it is // set after `await`, or in a `then`, `catch`, or `finally`, or in a setTimout/setInterval. export const useAsyncState = (initialState: T | (() => T)): [T, Dispatch>] => { const isMounted = useRef(true); const [state, setState] = useState(initialState); useEffect(() => { isMounted.current = true; return () => { isMounted.current = false; }; }, []); const setStateAction = useCallback>>((newState) => { isMounted.current && setState(newState); }, []); return [state, setStateAction]; };