反应-警告:无法在未安装的组件上调用setState(或forceUpdate)

时间:2018-10-04 19:35:15

标签: javascript reactjs

我从应用程序中的多个组件中收到以下错误。

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

导致此问题的组件之一在componentWillUnmount方法中具有调整大小的remove事件侦听器。我该如何解决此问题。从我在在线示例中看到的情况来看,通常使用这种方法取消订阅事件。

不允许粘贴特定代码,因此我正在编写伪代码

clickHandler() {
  this.setState({ opened: !(this.state.opened) });
}

componentDidMount() {
   this.setState({ width: window.innerWidth } );
   window.addEventListener('resize', this.updateWidth);
}

componentWillUnmount() {
    window.removeEventListener('resize', this.updateWidth);
}

private updateWidth() {
     if (this.state.opened &&
         window.innerWidth >= someMethodReturnsViewportConstant()) {

         this.onClickHandler();
         const htmlElement: HTMLInputElement =
             document.querySelector('#html-element-id');
         if (htmlElement && htmlElement) {
             htmlElement = false;
         }
     }
}

我所做的:

我已经阅读了Stack上与此有关的所有文章,但都没有解释为什么我的代码导致了这个问题。

2 个答案:

答案 0 :(得分:0)

由于您没有共享太多代码,因此我认为以下是您正在做的事情

this.updateWidth = setTimeout(() => {
   this.setState({
      width:100
   });
}, 3000);

componentWillUnmount() {
    clearTimeout(this.updateWidth);
}

所以无论您在setTimeout中进行seState还是在我提到的componentWillUnMount中清除它们

此外,如果您使用componentWillReceiveProps或componentDidUpdate,则需要使用nextProps或nextState检查当前道具或状态,如果它们不相等,则执行setState。此检查是强制性的。这也是您面临无限警告的原因

答案 1 :(得分:0)

正如其他人所说,您没有提供足够的代码来查看实际发生的情况。

但是,您可以做的是添加一个标志,以查看组件是否已卸载,以防止状态更新。

这是一个例子。

class ExampleComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      exampleState: []
    };
    this.isUnmounted = false;
    this.updateState = this.updateState.bind(this);
  }

  componentWillUnmount() {
    this.isUnmounted = true;
  }

  updateState() {
    if (!this.isUnmounted) { // Don't allow state change if component is unmounted
      this.setState({ exampleState: [1, 2, 3] });
    }
  }
}

现在您有了一个标志,可以用来调试状态更改。仔细检查您的组件状态是否会一次更改,最终您将发现警告的来源。