我有
useEffect(() => {
setLoading(true);
axios
.get(url, {params})
.then(data => {
setData(data || []);
setLoading(false);
})
.catch(() => {
showToast('Load data failed!', 'error');
setLoading(false);
});
}, [params]);
它给了我
警告:无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复,请取消使用useEffect清理功能中的所有订阅和异步任务。
好的,问题不是如何解决。当我在axios
承诺之后使用setLoading(false)时,它可以正常工作,但是在promise内(例如,上面),它总是向我发出警告。其实我想知道为什么会这样吗?简而言之,有没有人可以向我解释上面的代码流(上面的代码如何与警告一起工作的过程),并提供使用钩子的一些最佳实践。
答案 0 :(得分:2)
您需要清理功能。 这意味着您应该在useEffect函数的结尾调用函数。 当依赖关系发生变化时(例如您的示例)调用该函数。 这样我们就可以控制何时安装/卸载组件
useEffect(() => {
let cancelled = false;
setLoading(false);
async function fetchData() {
try {
const response = await axios.get(url, { params });
if (!cancelled) {
setData(response.data);
setLoading(false);
}
} catch (e) {
if (!cancelled) {
showToast(e.message, "error");
setLoading(false);
}
}
}
fetchData();
// clean up here
return () => {
cancelled = true;
};
}, [params]);
为什么会这样?
想象一下,您的请求速度很慢,并且异步请求完成时组件已经卸载。这次发出警告