javascript - 无法使用 useEffect 挂钩对未安装的组件执行 React 状态更新
问题描述
我有
useEffect(() => {
setLoading(true);
axios
.get(url, {params})
.then(data => {
setData(data || []);
setLoading(false);
})
.catch(() => {
showToast('Load data failed!', 'error');
setLoading(false);
});
}, [params]);
它给了我
警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。
好的,问题不在于如何解决。当我在 promise 之后使用 setLoading(false)时,axios
它工作正常,但在 promise 内部(例如上面)它总是给我警告。其实我想知道为什么会这样?有没有人可以简单地向我解释上面的代码流(上面的代码如何与警告一起工作的过程),并可能给出一些使用钩子的最佳实践。
解决方案
你需要清理功能。这意味着您应该调用 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]);
为什么会这样?
想象一下,您的请求变慢了,并且当异步请求完成时组件已经卸载。这次抛出这个警告
推荐阅读
- r - d = 0的ARMA和ARIMA之间的区别?
- html - 在表格中显示特定数据
- javascript - 如何从数组中检索和显示本地存储中的数据?
- vb.net - StreamWriter 将文件保存为 ANSI
- html - 图像映射的闪烁边框
- mysql - 错误 2020 (HY000):尝试从表中检索数据时,数据包大于“max_allowed_packet”字节
- raspberry-pi - 是否有任何带有 Alexa 语音服务的家庭自动化演示?
- javascript - 过滤 ng-repeat 时如何在过滤器上使用布尔变量?
- symmetricds - SymmetricDS:保持单独的自动增量计数器
- sql - 错误(6,87):PLS-00103:在预期以下/复合触发器之一时遇到符号“JOIN”