React 在安装或安装的组件上抛出错误可能是由于快速频繁地调用 setState()

React throwing error on mounting or mounted component may be due to rapid and frequent calls to setState()

我一直在开发一个组件,该组件需要在调整大小时跟踪页面的宽度。但是我能够做到这一点,但反应总是给我一个错误。

这是它抛出的错误:

warning.js:36 Warning: setState(...): Can only update a mounted or mounting component. 
This usually means you called setState() on an unmounted component. This is a no-op. 
Please check the code for the Nav component.

堆栈跟踪指向的导致错误的代码是 Nav 组件上的 handleResize() 方法。经过一些搜索和谷歌搜索后,我发现原因是 setState() 在组件安装之前被调用。这很奇怪,因为事件侦听器正在 componentDidMount() 中注册。一篇文章建议使用 componentWillMount No cigar。我不确定为什么会这样。可能是因为调整大小的速度如此之快?

  handleResize() {
    this.setState((prevState, currProps) => ({
      height: window.innerHeight,
      width: window.innerWidth
    }));
    if (this.props.showMenu === undefined) {
      if (this.state.width > (this.props.breakPoint || 767) && this.state.showMenu) {
        this.setState((prevState, currProps) => ({
          showMenu: false,
        }));
      }
    } else {
      if (this.state.width > (this.props.breakPoint || 767) && this.props.showMenu) {
        this.props.closeMenu();
      }
    }
  }

  componentDidMount () {
    window.addEventListener('resize', this.handleResize.bind(this));
  }

  componentWillUnmount () {
    window.removeEventListener('resize', this.handleResize.bind(this))
  }

this.handleResive.bind(this) 创建一个新函数,这意味着 window.removeEventListener('resize', this.handleResize.bind(this)) 也在创建一个新函数,而不是传递您最初添加的相同函数。这意味着您之前使用 bind 创建并添加的那个不会被删除,因为它不是同一个函数 (即使它的行为完全相同).

解决此问题的一种方法是在添加之前存储函数:

componentDidMount () {
    const resizeHandler = this.handleResize.bind(this);
    this.setState({resizeHandler});
    window.addEventListener('resize', resizeHandler);
}

componentWillUnmount () {
    window.removeEventListener('resize', this.state.resizeHandler);
    //you could cleanup state here but it's not necessary
}

如果有人有更好的方法来存储事件处理函数,请补充。