Here is the final code with everything working in case someone else comes back.

import {useState, useEffect} from "react";
import axios, {AxiosResponse} from "axios";

const useAxiosFetch = (url: string, timeout?: number) => {
    const [data, setData] = useState<AxiosResponse | null>(null);
    const [error, setError] = useState(false);
    const [errorMessage, setErrorMessage] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        let unmounted = false;
        let source = axios.CancelToken.source();
        axios.get(url, {
            cancelToken: source.token,
            timeout: timeout
        })
            .then(a => {
                if (!unmounted) {
                    // @ts-ignore
                    setData(a.data);
                    setLoading(false);
                }
            }).catch(function (e) {
            if (!unmounted) {
                setError(true);
                setErrorMessage(e.message);
                setLoading(false);
                if (axios.isCancel(e)) {
                    console.log(`request cancelled:${e.message}`);
                } else {
                    console.log("another error happened:" + e.message);
                }
            }
        });
        return function () {
            unmounted = true;
            source.cancel("Cancelling in cleanup");
        };
    }, [url, timeout]);

    return {data, loading, error, errorMessage};
};

export default useAxiosFetch;
Answer from Peter Kellner on Stack Overflow
Top answer
1 of 6
42

Here is the final code with everything working in case someone else comes back.

import {useState, useEffect} from "react";
import axios, {AxiosResponse} from "axios";

const useAxiosFetch = (url: string, timeout?: number) => {
    const [data, setData] = useState<AxiosResponse | null>(null);
    const [error, setError] = useState(false);
    const [errorMessage, setErrorMessage] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        let unmounted = false;
        let source = axios.CancelToken.source();
        axios.get(url, {
            cancelToken: source.token,
            timeout: timeout
        })
            .then(a => {
                if (!unmounted) {
                    // @ts-ignore
                    setData(a.data);
                    setLoading(false);
                }
            }).catch(function (e) {
            if (!unmounted) {
                setError(true);
                setErrorMessage(e.message);
                setLoading(false);
                if (axios.isCancel(e)) {
                    console.log(`request cancelled:${e.message}`);
                } else {
                    console.log("another error happened:" + e.message);
                }
            }
        });
        return function () {
            unmounted = true;
            source.cancel("Cancelling in cleanup");
        };
    }, [url, timeout]);

    return {data, loading, error, errorMessage};
};

export default useAxiosFetch;
2 of 6
13

Based on Axios documentation cancelToken is deprecated and starting from v0.22.0 Axios supports AbortController to cancel requests in fetch API way:

    //...
React.useEffect(() => {
    const controller = new AbortController();
    axios.get('/foo/bar', {
    signal: controller.signal
    }).then(function(response) {
     //...
     }).catch(error => {
        //...
     });
    return () => {
      controller.abort();
    };
  }, []);
//...
🌐
Plain English
plainenglish.io › blog › how-to-cancel-fetch-and-axios-requests-in-react-useeffect-hook
How to Cancel Fetch and Axios Requests in React’s useEffect Hook
October 20, 2023 - Throughout this article, we’ve delved into the importance of cleaning up side effects, explored practical examples, and learned about tools like the AbortController and axios.CancelToken that can help us manage and cancel requests effectively. Cleanup Matters: Always consider the cleanup of side effects when making network requests in React components. The useEffect hook provides an excellent place to manage these effects.
Discussions

useEffect cleanup with axios?
I’m confused about cleanup functions in useEffect hooks w/ axios. My component has an isLoading state as it’s getting the data from an API, and then the state changes to false once the data is displayed. This causes my component to render twice (‘loading’ first time, and populated with ... More on forum.freecodecamp.org
🌐 forum.freecodecamp.org
1
0
June 15, 2022
reactjs - How to cancel Axios request in useEffect when route changes in Next.js? - Stack Overflow
I am using Next.js v12 and Axios to fetch data in my application. When the navigation menu is used, a request is sent using Axios each time router.query.pid changes. However, if the request for tes... More on stackoverflow.com
🌐 stackoverflow.com
Cancel async Axios GET request - React hooks
Note that reloadConfig is a React ... triggering the useEffect hook and the Axios request. Problem is, if I click the button multiple times, no request is cancelled and a new one is created every time. I can see all the requests being treated in my terminal.... More on stackoverflow.com
🌐 stackoverflow.com
reactjs - Cancel Axios request in useEffect not running - Stack Overflow
I am attempting to cancel an axios request, but I am only having partial success. I have this function that returns a Promise when I make a GET request: const getCards = (token) => { const UR... More on stackoverflow.com
🌐 stackoverflow.com
May 22, 2020
🌐
DEV Community
dev.to › tmns › usecanceltoken-a-custom-react-hook-for-cancelling-axios-requests-1ia4
useCancelToken: a custom React hook for cancelling Axios requests - DEV Community
January 26, 2022 - The idea is that we create a cancel token and send it along with our request, which allows for us to cancel said request whenever we like. In our Modal component, this would look something like the following: const Modal = () => { const ...
🌐
freeCodeCamp
forum.freecodecamp.org › javascript
useEffect cleanup with axios? - JavaScript
June 15, 2022 - I’m confused about cleanup functions in useEffect hooks w/ axios. My component has an isLoading state as it’s getting the data from an API, and then the state changes to false once the data is displayed. This causes my component to render twice (‘loading’ first time, and populated with info the second time), which causes the axios api request within my useEffect fn to be called twice.
🌐
DEV Community
dev.to › pallymore › clean-up-async-requests-in-useeffect-hooks-90h › comments
[Discussion] Clean Up Async Requests in `useEffect` Hooks — DEV Community
so, inside my api function, I am creating new token on every request - if it's the same request though, then it cancels the prev token/req, and re-generate the token and handling everything related to axios inside this function. So, I will need to change it and basically create token inside useEffect.
🌐
YouTube
youtube.com › watch
Cancelling an Axios request in a useEffect hook - YouTube
This video shows how to cancel an Axios request before it completes. We'll use a useEffect hook and it's cleanup function to help us accomplish this.Source c...
Published   February 19, 2019
Find elsewhere
🌐
CodeSandbox
codesandbox.io › s › 4jwyq
Canceling Request With useEffect And Axios - CodeSandbox
February 5, 2021 - Canceling Request With useEffect And Axios by hamidpouladi using axios, react, react-dom, react-scripts
Published   Feb 05, 2021
Author   hamidpouladi
Top answer
1 of 5
8

Since you are depending on useEffect to fire up your request, you can use the cleanup function of useEffect to cancel your API request before a new one is executed.

function App() {
    useEffect(() => {
        let CancelToken = axios.CancelToken;
        let source = CancelToken.source();
        async function getPairs() {
            try {

                const res = await axios.get('http://localhost:3000/binance/pairs?timeframe='+timeframe+'&strat='+strat, {
                    cancelToken: source.token
                });

                if (res.status === 200 || res.data.status === 'success') {
                    setPairs(res.data.pairs);
                    setReloadConfig(false);
                }
            }
            catch (err) {
                if (axios.isCancel(err)) {
                    console.log("cancelled");
                } else {
                throw err;
                }
            }
        }
    
        // reloadConfig is a React useState hook that is set to true when clicking a button 
        if (reloadConfig) {
            getPairs();
        }

        return () => {
             source.cancel('Cancelled due to stale request');
        }
    }, [reloadConfig]);
}

export default App;

Note that you should define your cancel variable within useEffect otherwise it will be re-initialzed to undefined on next render if you directly define it within the component.

2 of 5
4

June 2022 Update

CancelToken has been deprecated since Axios v0.22.0 and should not be used in new projects (reference: https://axios-http.com/docs/cancellation). Use AbortController instead, like so:

function App() {
  useEffect(() => {
    const controller = new AbortController();
    async function getPairs() {
      try {
        const res = await axios.get(
          "http://localhost:3000/binance/pairs?timeframe=" +
            timeframe +
            "&strat=" +
            strat,
          {
            signal: controller.signal,
          }
        );

        if (res.status === 200 || res.data.status === "success") {
          setPairs(res.data.pairs);
          setReloadConfig(false);
        }
      } catch (err) {
        if (axios.isCancel(err)) {
          console.log("cancelled");
        } else {
          throw err;
        }
      }
    }

    // reloadConfig: React useState hook set to true when clicking a button
    if (reloadConfig) {
      getPairs();
    }

    return () => {
      controller.abort();
    };
  }, [reloadConfig]);
}

export default App;

Happy coding! Ciao.

🌐
DEV Community
dev.to › pallymore › clean-up-async-requests-in-useeffect-hooks-90h
Clean Up Async Requests in `useEffect` Hooks - DEV Community
October 12, 2019 - so, inside my api function, I am creating new token on every request - if it's the same request though, then it cancels the prev token/req, and re-generate the token and handling everything related to axios inside this function. So, I will need to change it and basically create token inside useEffect.
🌐
GitHub
github.com › use-hooks › react-hooks-axios › issues › 8
Cancel Request. · Issue #8 · use-hooks/react-hooks-axios
March 10, 2019 - I think about the implementation of canceling the request when the component is unmounted, cancel the previous request and add a type of debounce. What do you think about this? The text was updated successfully, but these errors were encountered: int64ago added the enhancement · New feature or request label · Mar 7, 2019 · Copy link · Member · Good propose! After reading the doc, it looks ok. Copy link · If this is to avoid calling setState on unmounted component, this might be simpler. React.useEffect(() => { let didCancel = false; // ...
🌐
Webpusher
webpusher.ie › hooks › loading › cancel
React hooks and REST - canceling in hooks - Webpusher
June 2, 2020 - We can push the details of how we setup the axios instance and cancel token into a module and now putting this all together, the updated React component is below · function YourComponent() { const [ isLoading, setIsLoading ] = useState(false); const [ theList, setTheList ] = useState([]); const { axiosClient, token } = createClient(); useEffect(() => { setIsLoading(true); axiosClient .get('/your/endpoint', { ...config, cancelToken: token, }) .then(response => { setTheList(response.data); }) .catch(error => { // we only want to run the state changing `setIsLoading` // if the error is not the s
🌐
Medium
medium.datadriveninvestor.com › aborting-cancelling-requests-with-fetch-or-axios-db2e93825a36
Aborting/Cancelling requests with Fetch or Axios | by Abhimanyu Chauhan | DataDrivenInvestor
January 4, 2024 - const cancelToken = axios.CancelToken; const source = cancelToken.source(); ... The source contains the cancel method, which can be invoked to abort/cancel the request. useEffect(() => { const cancelToken = axios.CancelToken; const source = ...
🌐
DevGenius
blog.devgenius.io › how-to-cancel-promises-and-api-calls-in-react-and-next-with-axios-️-3cc373ae14b8
How To cancel Promises and api calls in react and next with Axios ⚠️ | by josephat reyes | Dev Genius
July 4, 2023 - One way to handle it is by using the “useEffect” hook on the client-side and setting a control variable to check if the request should be aborted. Here’s an example of how to achieve this: import { useState, useEffect } from 'react'; import ...
🌐
Stack Overflow
stackoverflow.com › questions › 76050005 › in-react-using-axios-how-to-handle-request-cancel-on-component-unmount-if-the-re
reactjs - In react using axios how to handle request cancel on component unmount if the request is not done inside useEffect - Stack Overflow
As per my understanding, if a request is made inside a useEffect you can handle unmounting (not setting data if the component has unmounted) using abort controller and cleanup : useEffect(() => { const controller = new AbortController(); const ...
🌐
LogRocket
blog.logrocket.com › home › understanding react’s useeffect cleanup function
Understanding React’s useEffect cleanup function - LogRocket Blog
December 16, 2024 - We first store the CancelToken.source() from Axios in a constant named source, pass the token as an Axios option, and then cancel the request anytime with source.cancel(): useEffect(() => { const CancelToken = axios.CancelToken; const source ...
🌐
OpenReplay
blog.openreplay.com › integrating-axios-with-react-hooks
Integrating Axios with React Hooks
The most important property of ... in Axios request config, canceling the request is a matter of calling the abort() method on the controller instance....
🌐
Tazweid
tazweid.com › wifi-hacking › cancel-axios-request-in-useeffect.html
Cancel axios request in useeffect
Reading DOM properties before an ... A for Work. com is the number one paste tool since 2002. Axios has build in cancel method which gives you an opportunity to abort requests which aren t yet resolved or rejected....