React Hooks - Check If A Component Is Mounted

11 Jul 2019

If you’ve ever worked with a multi-page React app, you will invariably run into the dreaded warning in your console:

Warning: Can't perform a React state update on an unmounted component.

The most common cause of this warning is when a user kicks off an asynchronous request, but leaves the page before it completes. I especially wanted to know how to do this with hooks, because hooks are awesome.

I wanted to know how to avoid this classic React warning - here’s my solution.

const SampleComponent = () => {

    const [counter, setCounter] = useState(0)

    // Here's how we'll keep track of our component's mounted state
    const componentIsMounted = useRef(true)
    useEffect(() => {
        return () => {
            componentIsMounted.current = false
        }
    }. []) // Using an empty dependency array ensures this only runs on unmount

    const incrementCounterAsync = useCallback(()=> {
        async () => {
            try {
                await someLongRunningProcess()
                if (componentIsMounted.current) {
                    setCounter(counter + 1)
                }
            } catch (err) {
                // Handle your error
            }
        }
    }, [setCounter])

    render (
        // Display the counter + a button to increment it
    )
}

To explain the above code snippet, imagine we have a sample component that simply displays a counter, and a button to increment the counter.

When we click the button, it fires off someLongRunningProcess() - this could be a backend operation or whatever. Use your imagination.

When someLongRunningProcess() has completed, we make sure we’re still mounted via the componentIsMounted variable! If the component is still mounted, we can modify the state, no problem. If it’s not mounted - hey, that’s alright, we won’t touch the state.

This will dodge that nasty React warning! Have fun!