为什么会出现此错误?
警告:无法在已卸载的设备上调用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>
);
}
答案 0 :(得分:4)
就像其他人提到的那样,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;
}
答案 1 :(得分:0)
删除此
componentWillUnmount() {
this.setState({ posts: null });
}
没用
来自文档:
您不应在componentWillUnmount()中调用setState(),因为 组件将永远不会被重新渲染。一旦组件实例是 卸载后,将不再安装。
https://reactjs.org/docs/react-component.html#componentwillunmount
答案 2 :(得分:0)
反应组件的状态是本地实体。卸载的组件没有状态,无需这样做。 React已经告诉您这是no-op
,这意味着在技术方面无法操作。这意味着您要告诉组件在其已被破坏时执行某些操作。
https://reactjs.org/docs/react-component.html#componentwillunmount
您不应在componentWillUnmount()中调用setState(),因为永远不会重新渲染该组件。卸载组件实例后,将永远不会再次安装它。
答案 3 :(得分:0)
您可以尝试以下代码:
.stackarea
通过使用_isMounted,仅在安装了组件时才调用setState。答案只是在设置状态之前进行检查以查看是否已安装组件。