在卸载父级后停止子级更新

时间:2016-10-07 03:16:18

标签: reactjs

小问题 - 不确定如何处理在卸载其父级后阻止子级更新。

目前我有一个'view'(父级),其中嵌套了TextField组件。

我的TextField组件使用onBlur

实现输入
<input type={this.props.type} name={this.props.name} onBlur={this.handleBlur} ... />

TextField组件中的两个函数是

hideClear: function () {
    // to prevent clear button from disappearing when clicking on it
    if (!this.state.keepFocus) {
        this.setState({inFocus: false});
    }
},
handleBlur: function (e) {
    e.preventDefault();
    this.setState({keepFocus: false});
    window.setTimeout(this.hideClear, 200);
},

现在,当我的父母在我的输入字段有焦点的情况下卸载时,我会回来

警告:setState(...):只能更新已安装或安装的组件。这通常意味着您在已卸载的组件上调用了setState()。这是一个无操作。请检查TextField组件的代码。

我希望我可以就如何处理这种情况获得一些好的建议。

谢谢:)

1 个答案:

答案 0 :(得分:1)

如错误所示,您正在尝试更新组件已卸载时的组件状态,这是由于handlerBlur()功能中的计时器所致。

我想,我不太确定,但每当组件卸载时输入都会失去焦点,因此onBlur事件会触发handleBlur()函数,因此设置一个带有setTimeout的计时器,通过hideClear()功能,在已卸载组件后,实质上更新组件的状态。

  

最佳解决方案是找到卸载组件后可能调用setState()的位置,并修复它们。这种情况最常发生在回调中,当组件等待某些数据并在数据到达之前卸载时。理想情况下,在卸载之前,应在componentWillUnmount中取消任何回调。

上述引文摘自React developer's blog

解决此问题的一种快速方法是将计时器的标识符存储在实例变量中,以便在卸载组件时使用window.clearTimeout清除计时器。

var MyComponent = React.createClass({

  timerId = 0,

  ...

  handleBlur: function (e) {
    e.preventDefault();
    this.setState({keepFocus: false});
    this.timerId = window.setTimeout(this.hideClear, 200);
  },

  componentWillUnmount: function() {
    if (this.timerId) 
      window.clearTimeout(this.timerId);
  },

  ...

}