Can’t perform a React state update on an unmounted component.
React hooks allow us to easily create and update state. The problem is that we can also have asynchronous code that finalizes after a component has been unmounted. To fix this we can use two simple hooks.
useIsMounted hook
We can detect if a component has been unmounted.
useMountedState hook
We can use the above hook to our advantage and create a state hook which automatically checks before trying to update.
We use React.useCallback
to prevent unnecessary re-renders from whatever component that uses the function as a dependency for other React.useEffect
s.
Usage
This component will now only update the state if the component is still mounted.
See it in action
If you see “delayed” in the UI and do not see an error in the console, then the code is working as it is supposed to.
TL;DR:
Feel free to copy paste the following code to use these two hooks.
import { useCallback, useEffect, useRef, useState } from 'react'
export function useIsMounted() {
const mounted = useRef(false)
const isMounted = useCallback(() => mounted.current, [])
useEffect(() => {
mounted.current = true
return () => (mounted.current = false)
}, [])
return isMounted
}
export function useMountedState(init) {
const isMounted = useIsMounted()
const [state, setState] = useState(init)
const setStateCallback = useCallback(
(...args) => {
if (isMounted()) {
return setState(...args)
}
return null
},
[isMounted, setState],
)
return [state, setStateCallback]
}