【问题标题】:React - Warning: Can't call setState (or forceUpdate) on an unmounted componentReact - 警告:无法在未安装的组件上调用 setState(或 forceUpdate)
【发布时间】:2019-03-10 06:32:23
【问题描述】:

我的应用程序中的几个组件出现以下错误。

警告:无法在未安装的组件上调用 setState(或 forceUpdate)。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请在 componentWillUnmount 方法中取消所有订阅和异步任务。

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

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

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 上有关此问题的所有帖子,但没有人解释我的代码导致此问题的原因。

【问题讨论】:

  • 如果您在 setTimeout 中执行 setState,请确保使用 clearTimeout() 函数在 componentWillUnMount 中清除所有这些
  • 我没有在任何地方使用 setTimout。我在 componentWillMount 方法中订阅事件监听器并将状态设置为 this.setState({ width: window.innerWidth } );
  • 您在组件中使用的是 componentWillRecieveProps 还是 componentDidUpdate?
  • 我没有使用它们。
  • 抱歉 给定的代码帮不了你太多。需要查看问题的完整组件代码

标签: javascript reactjs


【解决方案1】:

由于您没有共享太多代码,所以我假设以下是您正在做的事情

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

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

所以无论您在 setTimeout 中执行 seState 的任何位置,都像我提到的那样在 componentWillUnMount 中清除它们

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

【讨论】:

  • 我不得不编辑一些代码,因为我受限于共享代码,但这基本上是正在做的事情。没有使用 setIntervals 或超时。
【解决方案2】:

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

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

这是一个例子。

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] });
    }
  }
}

现在您有了一个可以调试状态更改的标志。逐一检查你的组件状态变化,最终你会发现警告来自哪里。

【讨论】:

    猜你喜欢
    • 2018-11-03
    • 2019-01-26
    • 2019-01-07
    • 1970-01-01
    • 2019-08-23
    • 2023-04-08
    • 2018-10-28
    • 1970-01-01
    • 2019-06-06
    相关资源
    最近更新 更多