Carsten Ruhr

Make sure to abort fetch requests on unmount

If you use a useEffect hook in React to fetch some data from a server, you should make sure to cancel this request when the component gets unmounted.
To be honest, I am quite guilty of a fire-and-forget mindset when it comes to requests. But hey, there is always room to improve. That's why I hope to remember this once I wrote it down here.

Let's assume a useEffect usage like this:

useEffect(() => {

    const doRequest = async () => {
        const result = await fetch('...')
        return await result.json()
    }

    const data = doRequest()
        .catch(err => console.error(err))

    [...]
}, [])

Now imagine the component gets mounted, but the user - impatient as they usually are - switches to a different page before the request had a chance to finish. No problem. The request finishes in the background, and nothing really happens with the result afterwards. So - no reason to worry, right?
Most of the time, yes. Except when you want to free the resource to make space for other requests. And let's be honest: You want to free all unneeded resources as fast as possible. Always.
So let's make use of a little helper called the AbortController to make sure the request gets cancelled when the component is unmounted:

useEffect(() => {
    const myAbortController = new AbortController()
    const signal = myAbortController.signal

    const doRequest = async () => {
        const result = await fetch('...', { signal })
        return await result.json()
    }

    const data = doRequest()
        .catch(err => console.error(err))

    [...]

    return () => {
        myAbortController.abort()
    }
}, [])

And the same works also with axios requests.

Alright, I have no excuse to forget about this anymore. Let's try to be resourceful in a time when simple websites are getting bigger and bigger (yes, I am guilty of this as well).