[英]How to abort Axios request in React apps using async/await?
Hi I created a React hook to handle Axios requests.嗨,我创建了一个 React 钩子来处理 Axios 请求。 The trouble I'm having is that I'm unable to successfully abort the request to prevent memory leak.
我遇到的麻烦是我无法成功中止请求以防止内存泄漏。 When I switch between 2 pages that uses the hook, I get error:
当我在使用钩子的 2 个页面之间切换时,出现错误:
Can't perform a React state update on an unmounted component.
无法对未安装的组件执行 React 状态更新。 This is a no-op, but it indicates a memory leak in your application.
这是一个空操作,但它表明您的应用程序中存在内存泄漏。 To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。
useAxios hook code:使用Axios挂钩代码:
import { useState, useEffect } from "react";
import axios from "axios";
const useAxios = (url, method = "GET") => {
const [data, setData] = useState([]);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
const [body, setBody] = useState(null);
useEffect(() => {
const controller = new AbortController();
const getData = async (body) => {
setLoading(true);
try {
const res = body
? await axios.post(url, body, {
signal: controller.signal,
})
: await axios.get(url, {
signal: controller.signal,
});
setData(res.data);
setError(null);
setLoading(false);
} catch (err) {
console.log(err.message);
setError(err.message);
setLoading(false);
}
};
if (method === "GET") {
getData();
} else if (method === "POST") {
getData(body);
}
return () => {
controller.abort();
};
}, [url, method, body]);
return { data, error, loading, setBody };
};
export default useAxios;
Your setError
and setLoading
are both going to fire when aborting.您的
setError
和setLoading
在中止时都会触发。
So you will want to set a flag in the unmount callback.因此,您需要在卸载回调中设置一个标志。 You can then conditionally call
setError
/ setLoading
based on this.然后,您可以基于此有条件地调用
setError
/ setLoading
。
useEffect(() => {
let aborting = false;
try {
....
} catch (err) {
console.log(err.message);
if (!aborting) {
setError(err.message);
setLoading(false);
}
}
....
return () => {
aborting = true;
controller.abort();
}
}, ...
prevent memory leak
防止内存泄漏
Just a note, this wound't actually be a memory leak, it's just a warning that it could have come from one.请注意,这个伤口实际上并不是内存泄漏,它只是一个警告,它可能来自一个人。 eg.
例如。 using
addEventListener
without removeEventListener
.使用
addEventListener
而不使用removeEventListener
。 But in either case you would still want to prevent a setState
on a umounted component.但在任何一种情况下,您仍然希望在已卸载的组件上阻止
setState
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.