javascript - 无法在未安装的组件上调用 setState(或 forceUpdate)。这是一个无操作,但它表明您的应用程序中存在内存泄漏
问题描述
为什么我会收到此错误?
警告:无法在未安装的组件上调用 setState(或 forceUpdate)。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 componentWillUnmount 方法中的所有订阅和异步任务。
postAction.js
export const getPosts = () => db.ref('posts').once('value');
成分:
constructor(props) {
super(props);
this.state = { posts: null };
}
componentDidMount() {
getPosts()
.then(snapshot => {
const result = snapshot.val();
this.setState(() => ({ posts: result }));
})
.catch(error => {
console.error(error);
});
}
componentWillUnmount() {
this.setState({ posts: null });
}
render() {
return (
<div>
<PostList posts={this.state.posts} />
</div>
);
}
解决方案
正如其他人所提到的, componentWillUnmount 中的 setState 是不必要的,但它不应该导致您看到的错误。相反,可能的罪魁祸首是这段代码:
componentDidMount() {
getPosts()
.then(snapshot => {
const result = snapshot.val();
this.setState(() => ({ posts: result }));
})
.catch(error => {
console.error(error);
});
}
由于 getPosts() 是异步的,因此可能在它解析之前,组件已被卸载。您没有对此进行检查,因此 .then 可以在组件卸载后最终运行。
为了解决这个问题,您可以在 willUnmount 中设置一个标志,并在 .then 中检查该标志:
componentDidMount() {
getPosts()
.then(snapshot => {
if (this.isUnmounted) {
return;
}
const result = snapshot.val();
this.setState(() => ({ posts: result }));
})
.catch(error => {
console.error(error);
});
}
componentWillUnmount() {
this.isUnmounted = true;
}
推荐阅读
- swift - Swift - 如何在不让应用挂起的情况下等待某事
- bluedata - 如何将 docker 参数(例如 `--cap-add=XXX`)传递给在 BlueData 中运行的 docker 实例?
- scala - 如何在akka中处理Slick db对象
- python - strptime 无法解析给定正确的格式
- android - 一个有 2 个标签的片段,没有 viewpager
- java - 如何在java中使用replace函数来获取不区分大小写的字符值
- c# - 具有继承和 Automapper 映射的 EF Core:如何使用继承查询和映射 SQL 视图
- java - 是否可以创建一个以类为节点的树结构?
- python - 包括定期约会
- google-sheets - 如何根据单独列中的日期获取某物的价格?