反应:是否可以通过将 this.setState 设置为空函数来防止卸载后的状态更新?



>我遇到了一个问题,即网络回调试图设置未挂载组件的 State() 并收到有关此无操作的默认控制台警告。

我无法跟踪卸载发生的原因,但我找到了一个解决方案,建议在 componentWillUnmount() 中将函数设置为无。它不起作用,我测试将this.setState设置为无。见下文。

错误消失了,但我想问一下这是否是一个有效的解决方案。这里的代码:

componentDidMount() {
this.fetchLogItems(10, 'recentChanges');
}
componentWillUnmount() {
this.setState = () => {};
}
fetchLogItems = (limit, stateRef) => {
let tmpObj = {};
base.fetch('_changelogs', {
context: this,
then(data) {
tmpObj[stateRef] = {...data}
tmpObj.loading = false;
this.setState({...tmpObj})
},
catch(err){console.error(err)}
});
};

两个选项:

  • 确保您使用的任何帮助程序也允许使用"析构函数"(取消,我绝对更喜欢使用"取消")
  • 如果没有,那么您可以在您的班级中引入一个"标志">

如果您的库允许进行一些"取消"、"销毁"或"清理",那么您只需执行以下操作:

componentWillUnmount() {
base.cancelFetch(); // or something similar.
}

否则,您可以向组件引入属性。也许把它命名为isUnmounted.在componentWillUnmount中,将this.isUmounted设置为 true。将this.setState调用包装在if-语句中,该语句检查isUnmounted是否为 false,如果是,则可以调用this.setState。这实际上是一个非常常见的模式。

它可能">感觉"丑陋,但事实上,这种模式在 React 开发人员中似乎是惯用的。如果没有,至少它是解决与您类似问题的务实解决方案。

constructor() {
// HERE
this.isUmounted = false;
}
componentDidMount() {
this.fetchLogItems(10, 'recentChanges');
}
componentWillUnmount() {
// HERE
this.isUmounted = true;
}
fetchLogItems = (limit, stateRef) => {
let tmpObj = {};
base.fetch('_changelogs', {
context: this,
then(data) {
tmpObj[stateRef] = {...data}
tmpObj.loading = false;
// WRAP THE `this.setState` here.
if (!this.isUnmounted) {
this.setState({...tmpObj})
}
},
catch(err){console.error(err)}
});
};

但是,我更喜欢使用支持取消的库和帮助程序。这绝对可以保证一定程度的清理。如果不取消,我们将面临引入内存泄漏的风险。

最新更新