2017-03-31 116 views
1

我面临的问题是网络回调尝试setMate()的未挂载组件,并收到有关此no-op的默认控制台警告。React:是否可以通过设置this.setState来清空函数来防止卸载后的状态更新?

我不可能跟踪为什么发生卸载,但我找到了一个解决方案,建议在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)} 
    }); 
    }; 

回答

2

两个选项:

  • 确保您正在使用也不管助手允许使用“析构函数”(取消,我肯定更喜欢使用“取消的“)
  • 如果没有,那么你可能会推出一个‘标志’到您的类

如果库允许一些‘取消’,‘毁灭’,或‘清理’,那么你可以简单地做:

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

否则,您可以到物业介绍给您的组件。也许将其命名为isUnmounted。在componentWillUnmount中,将this.isUmounted设置为true。将this.setState调用包含在if中 - 用于检查isUnmounted是否为假的陈述,如果是,则可以调用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)} 
    }); 
}; 

但是,我更喜欢使用支持取消的库和帮助程序。这绝对保证了一定程度的清理。没有取消,我们冒着引入内存泄漏的风险。

相关问题