componentDidMount:无法在已卸载的组件上调用setState(或forceUpdate) [英] componentDidMount: Can't call setState (or forceUpdate) on an unmounted component

查看:294
本文介绍了componentDidMount:无法在已卸载的组件上调用setState(或forceUpdate)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在componentDidMount中获取数据并更新状态,并且出现了著名的警告:

I am fetching data in componentDidMount and updating the state and the famous warning is appearing:

警告:无法在已卸载的组件上调用setState(或forceUpdate).这是空操作,但是它表明您的应用程序中发生内存泄漏.要解决此问题,请取消componentWillUnmount方法中的所有订阅和异步任务.

Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.

我的代码如下:

componentDidMount() {
    let self = this;

    let apiBaseUrl = Config.serverUrl;
    axios.get( apiBaseUrl + '/dataToBeFetched/' )
        .then( function(response) {
            self.setState( { data: response.data } );;
        } );
}

造成此警告的原因是什么?获取数据和更新状态的最佳方法是什么?

What is causing this warning and what is the best way to fetch the data and update the state?

推荐答案

基于先前的答案,我已经完成了以下工作:

Based on a previous answer, I have done the following which worked fine:

constructor(props) {
   this.state = {isMounted: false}
}

componentDidMount() {
    let apiBaseUrl = Config.serverUrl;
    this.setState( { isMounted: true }, () => {
        axios.get( apiBaseUrl + '/dataToBeFetched/' )
            .then( (response) => { // using arrow function ES6
                if( this.state.isMounted ) {
                    this.setState( { pets: response.data } );
                }
            } ).catch( error => {
                // handle error
        } )
    } );
}

componentWillUnmount() {
    this.setState( { isMounted: false } )
}

另一个更好的解决方案是按以下方式取消卸载中的请求:

Another better solution is to cancel the request in the unmount as follows:

constructor(props) {
    this._source = axios.CancelToken.source();
}

componentDidMount() {
    let apiBaseUrl = Config.serverUrl;
    axios.get( apiBaseUrl + '/dataToBeFetched/', { cancelToken: this._source.token } )
        .then( (response) => { // using arrow function ES6
            if( this.state.isMounted ) {
                this.setState( { pets: response.data } );
            }
        } ).catch( error => {
            // handle error
    } );
}

componentWillUnmount() {
    this._source.cancel( 'Operation canceled due component being unmounted.' )
}

这篇关于componentDidMount:无法在已卸载的组件上调用setState(或forceUpdate)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆