The Abortcontroller signal is not working for me with Axios in React.
I wanted to replace CancelToken (as it's deprecated) with the AbortController, but it is not working, respectively the requests are not being canceled.
let testController: AbortController;
function loadTest() {
testController = new AbortController();
TestAPI.getTest(testController.signal)
.then((e) => {
console.log(e.data);
})
.catch((e) => {
console.error(e);
});
}
Also in the UseEffect Cleanup I do this (here it should cancel) and also the signal's state is set to aborted, but still the request is not canceled:
useEffect(() => () => {
if (testController) testController.abort();
// console.log(testController.signal.aborted) => **true**
}, []);
Here is my API, where I pass the AbortSignal to the request:
getTest(signal?: AbortSignal): Promise<AxiosResponse<Test[]>> {
return axios.get(`${URI}/test`, { signal });
},
When using Axios.CancelToken.source was working fine, but now with the AbortController, the request is never canceled.
Using: "axios": "^0.26.0",
Did someone manage to integrate the AbortController with React and Axios? Or does the AbortController only work with fetch?
According to the docs axios supports the AbortController of the fetch API.
Cancellation
Axios supports AbortController to abort requests in fetch API way:
const controller = new AbortController(); axios.get('/foo/bar', { signal: controller.signal }).then(function(response) { //... }); // cancel the request controller.abort()
It's not clear exactly where testController is declared:
let testController: AbortController;
but I suspect it's in the body of the function component and redeclared on a subsequent render cycle.
I suggest using a React ref to store an AbortController, and reference this ref value around your app. This is so the component holds on to a stable reference of the controller from render cycle to render cycle, to be referenced in any useEffect hook cleanup function to cancel in-flight requests if/when the component unmounts.
const abortControllerRef = useRef<AbortController>(new AbortController());
function loadTest() {
TestAPI.getTest(abortControllerRef.current.signal)
.then((e) => {
console.log(e.data);
})
.catch((e) => {
console.error(e);
});
}
useEffect(() => {
const controller = abortControllerRef.current;
return () => {
controller.abort();
};
}, []);
I would recommend to read this post.
In a nutshell you would like to use useEffect to create controller, and, what is more important, to use return statement to abort the controller.
useEffect(() => {
const controller = new AbortController();
const signal = controller.signal;
getData(signal)
//cleanup function
return () => {controller.abort();};
}, [fetchClick]);
getData function can then be your axios call in the form:
const getData = async (signal) =>{
const res = await axios.get(url, {signal: signal}).then(...)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With