开发者问题收集

未捕获的 RangeError:React 中超出最大调用堆栈大小

2017-11-08
802

我收到了

ERROR: "Uncaught RangeError: Maximum call stack size exceeded"

我怀疑 componentWillUpdate 方法中的这段代码是导致错误的原因,因为我在添加代码后才收到错误。我这里做错了什么吗?

componentWillUpdate(nextProps, nextState) {

...

if (nextProps.show) {
  for (var i = 0; i < this.props.data.actions.length; i++) {
    if (this.props.data.actions[i].assignedTo !== this.state.userId && this.state.showActions === true) {
      this.setState({ showActions: false })
    }
    if (this.props.data.actions[i].assignedTo === this.state.userId && this.state.showActions === false) {
      this.setState({ showActions: true })
    }
  }
 }

...

}

单击按钮时,nextProps.show 设置为 true,然后它会检查分配了操作的人是否与登录的用户相同,然后它会将状态 showActions 设置为 true。如果满足代码中的条件,则此状态用于显示/隐藏行

3个回答

由于您正在设置 state ,这将再次调用 componentWillUpdate ,因此此递归调用是堆栈超出的原因。

componentWillMount() 不同,我们不应在 componentWillUpdate() 中调用 this.setState() 。我们不调用 this.setState() 的原因是该方法会触发另一个 componentWillUpdate() 。如果我们在 componentWillUpdate() 中触发状态更改,我们将陷入无限循环。

Muhammad Faizan
2017-11-08

this.state 尚未在 componentWillUpdate 中发生变异。

因此,使用 nextState 而不是 this.state 来验证使用 this.setState 后值是否正确:

componentWillUpdate(nextProps, nextState) {

...

if (nextProps.show) {
  for (var i = 0; i < this.props.data.actions.length; i++) {
    if (this.props.data.actions[i].assignedTo !== this.state.userId && nextState.showActions === true) {
      this.setState({ showActions: false })
    }
    if (this.props.data.actions[i].assignedTo === this.state.userId && nextState.showActions === false) {
      this.setState({ showActions: true })
    }
  }
 }

...

}
Damien Leroux
2017-11-08

根据 React componentWillUpdate 文档 :

Note that you cannot call this.setState() here; nor should you do anything else (e.g. dispatch a Redux action) that would trigger an update to a React component before componentWillUpdate() returns. If you need to update state in response to props changes, use componentWillReceiveProps() instead.

您应该将代码移至 componentWillReceiveProps 方法。

pwolaq
2017-11-08