如何避免异步操作在未安装的组件上设置状态?

时间:2019-02-07 16:21:17

标签: reactjs react-native asynchronous synchronization

让我们想象一个组件使用 fetch 从服务器加载数据。

fetch(`${url}`).then(response => {
                    this.setState({
                        ...
                    })
                })

但是有可能在卸载该组件后加载数据,这将导致尝试在已卸载的组件上 setState

这样的问题有多严重?如何避免它发生?

2 个答案:

答案 0 :(得分:1)

您将要看看AbortController class。与使用_mounted is considered一样使用反模式:

drawBeats()

调用控制器的class Test extends React.ComponentComponent { componentDidMount() { this.controller = new AbortController(); fetch(`${url}`, { signal: controller.signal }).then(response => { this.setState({ }) }) } componentWillUnmount() { this.controller.abort() } } 功能将取消您的abort。我建议在fetch生命周期函数中调用它。

浏览器兼容性:https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort#Browser_compatibility

答案 1 :(得分:0)

这是无操作的,因为它什么都不做,但是如果状态有些“大”或资源过多,则可能导致很少的内存泄漏

我在React Navigation v2模块的抽屉导航器中遇到了这个问题,我做了一个肮脏的解决方法,方法是通过一个变量告诉我组件是否已安装

class Modal extends React.PureComponent {
....
_mounted=false;
componentDidMount(){this._mounted = true}
componentWillUnmount(){this._mounted = false}
....

然后每次我调用setstate时,我都会先检查this._mount是否为真。

现在,在React Navigation v3中,抽屉无法卸载屏幕,所以我很高兴不使用它