Cancel Axios request to prevent React from yelling at you.
Tags: webdev, javascript, react
Published: 2020-06-18 15:13:01

---
title: Cancel Axios request to prevent React from yelling at you.
published: true
description: In this article we will have a look at how to cancel a Axios Http request to prevent errors when updating state in an unmounted react component.
canonical_url: https://since1979.dev/cancel-axios-request-to-prevent-react-from-yelling-at-you/
cover_image: https://since1979.dev/wp-content/uploads/2020/06/cancel-axios-in-react.jpg
tags: webdev, javascript, react
---
[Originally posted on my website on June 17th 2020](https://since1979.dev/cancel-axios-request-to-prevent-react-from-yelling-at-you/)

Canceling Axios and prevent state update.
-----------------------------------------

In this article i would like to show you how we can cancel a [Axios](https://github.com/axios/axios) Api requests. Now why would we want to do that!? Well their could be a couple of reasons like saving our users bandwidth, but in this example lets focus on another reason.

Let's say we make a Api request and want to update the components state with the response data. When the user for some reason moves away from our component, when the request isn't finished, the request will try and update the no longer existent component state. And this will result in [React](https://reactjs.org/) yelling at us that we made a mistake become this is not allowed.

Automatically canceling the Axios request when the component unmounts will prevent this error and the screaming in our console.

### Building a little test case.

First we have to make a little test case app. The example below is pretty silly, but you can compare it with a app that has a react router, where our user is frantically clicking between different menu items, mounting and unmounting our components.

```js
import React, { useState } from "react";
import ComponentWithRequest from "./components/ComponentWithRequest";

const App = () => {
  const [mounted, setMounted] = useState(true);

  return (
    <div className="App">
      {mounted && (
        <ComponentWithRequest
          toggleMounted={() => {
            setMounted(!mounted);
          }}
        />
      )}
    </div>
  );
};

export default App;
```

Here we create a App component that has a *mounted* state that initializes to *true*. As long as mounted is *true* we render a *ComponentWithRequest* component and we pass it a *toggleMounted* prop function that when called toggles the *mounted* state to *false* using the *setMounted* function. And that will unmount the *ComponentWithRequest*.

#### The ComponentWithRequest component

```js
import React, {useEffect} from "react";

const ComponentWithRequest = props => {

    useEffect(() => {
    
        props.toggleMounted();
        
    }, [props]);

    return (
        <div className="box">
            <p>I will immediately get unmounted.</p>
        </div>
    );
};

export default ComponentWithRequest;
```

Inside the *ComponentWithRequest* component we have a *useEffect* hook that runs when the component gets rendered. Inside the *useEffect* we call the *toggleMounted* function we received as a prop.

So all of this will mount the *ComponentWithRequest* when our app runs, and then it will immediately unmount it again simulating the user that is clicking around moving away from out component.

### Making the Axios request.

Now we can add the Axios request to see what happens.

```js
import React, {useState, useEffect} from "react";
import axios from "axios";

const ComponentWithRequest = props => {

    const [apiData, setApiData] = useState(null);

    useEffect(() => {

        axios.get("https://jsonplaceholder.typicode.com/todos").then(response => {
            setApiData(response.data);
        });

        props.toggleMounted();
      
    }, [props]);

    return (
        <div className="box">
            <p>I will immediately get unmounted.</p>
        </div>
    );
};

export default ComponentWithRequest;
```

In the code above we add a *apiData* state using the *useState* hook. And in the *useEffect* function we use Axios to make a request to the JSONPlaceholder api.

After we start the request we call the *toggleMounted* function, effectively unmounting the component. Now the Axios request continues none the less and when it receives it's response it will try to update the component's no longer existing *apiData* state. resulting in the nasty warning shown in the image below.

![](https://since1979.dev/wp-content/uploads/2020/06/react-update-state-error.png)

![](https://since1979.dev/wp-content/uploads/2020/06/tbbt-1.gif)

### Auto cancel the request when component unmounts.

Let's fix the problem by changing our code to auto cancel the Axios request when our component unmounts.

```js
import React, {useState, useEffect} from "react";
import axios from "axios";


const ComponentWithRequest = props => {

    const [apiData, setApiData] = useState(null);

    useEffect(() => {
        const source = axios.CancelToken.source();

        axios.get("https://jsonplaceholder.typicode.com/todos", {
            cancelToken: source.token
        }).then(response => {
            setApiData(response.data);
        }).catch(err => {
            console.log("Catched error: " + e.message);
        });

        props.toggleMounted();

        return () => {
            source.cancel("Component got unmounted");
        };
    }, [props]);

    return (
        <div className="box">
            <p>I will immediately get unmounted.</p>
        </div>
    );
};

export default ComponentWithRequest;
```

Inside the *useEffect* function we now first grab a *CancelToken Source* from Axios and store it in a constant named *source*. We can use this to get a CancelToken and actually cancel the request.

Next we pass a config object to our Axios request setting the *cancelToken* key to a *token* we get from the *source* object.

Now we have to add a catch block to our request because canceling the request will throw an error, and if we don't catch that we will have a new bug on our hands. So we catch the error and simply log out the error message.

Finally we return a function from the *useEffect* function. This function gets called when our component unmounts. Inside this function we call the *cancel* method on our *source* object and we pass it a little message saying why the request got canceled. This message is passed to the error object in our catch block, so that is what will get logged out there.

![](https://since1979.dev/wp-content/uploads/2020/06/request-canceled.png)

Now when our component gets unmounted the Axios Http request gets canceled before it tries to update the component state. And as you can see in the image above, we now get a friendly log message instead of that nasty warning we got before.

![](https://since1979.dev/wp-content/uploads/2020/06/sheldon-1.gif.8376f37eafea09ecbed67f175b76de5c-1.gif)

### CodeSandBox

If you want to play around with the code i have set up a [CodeSandBox](https://codesandbox.io/s/cancel-axios-jokks?file=/src/components/ComponentWithRequest.js) for you to have a look at. You can comment out the call to *source.cancel()* on line 31 of the *ComponentWithRequest.js* file and refresh the little browser to see for yourself what happens if we don't cancel the request.

### Follow?

Let's connect on twitter [@Vanaf1979](https://twitter.com/Vanaf1979) or here on Dev.to [@Vanaf1979](https://dev.to/vanaf1979) so i can notify you about new articles, and other web development related resources.

**Thanks for reading and stay safe.**