使用componentDidUpdate

时间:2018-10-07 00:58:07

标签: javascript reactjs

我试图通过3个步骤创建一个基本的向导。在我的根文件中,在构造函数中设置状态:

constructor(props) {
    super(props);
    this.state = {
      currentStep: 1,
      data: {
        firstname: 'James',
        surname: 'Smith',
        country: 'Australia',
      },
    };

“我的向导”具有3个“步骤”,下面是一个示例渲染步骤的示例:

<DataEntry currentStep={this.state.currentStep} data={this.state.data} afterValidate={this._nextStep} moveBack={this._prevStep} />

然后在该步骤中,我的构造函数是:

  constructor(props) {
    super(props);
    this.state = { data: this.props.data };
    this._validate = this._validate.bind(this);
    console.log(this.state);
  }

因此,我根据作为“数据”传入的道具设置了步的状态。

我的onChange是通用的,因此每个“字段”都有一个onchange,可以这样做:

  onChange(fieldName, fieldValue) {
    const thisData = { ...this.state.data, [fieldName]: fieldValue };
    this.setState({ data: thisData });
  }

当我使用“下一步”按钮转到下一步时,我在“步骤”组件中调用了一个方法:

  _validate() {
    console.log('Validating...');
    this.props.afterValidate(this.state.data);
  }

这将调用我的父组件中的方法来更新数据:

  _nextStep(data) {
    console.log('Next');
    let currentStep = this.state.currentStep;
    console.log(currentStep);
    currentStep = currentStep >= 2 ? 3 : currentStep + 1;
    this.setState({ currentStep, data }, ()=>{console.log('New state: ', this.state)});
  }

这项工作。但是这个问题是我似乎陷入了一个循环,因为我需要更新其他“步骤”组件中的状态。每个步骤都有:

  componentDidUpdate() {
    console.log('Data Entry got Prop Update...');
    this.setState({ data: this.props.data });
  }

因此,当父级中的状态更新时,它需要在步骤中更新状态...但是我似乎陷入了暴力循环:

  

未捕获的错误:超出最大更新深度。当   组件重复调用componentWillUpdate内的setState或   componentDidUpdate。 React将嵌套更新的数量限制为   防止无限循环。

我猜想正在为它们全部调用'componentDidUpdate',因为父状态基本上更新了所有步骤,然后它们又通知父状态已更新?

实现此目标的正确方法是什么?基本上,我希望父级中的数据成为真相的来源,然后在每个“步骤”中更新,以更新此状态,并传播到步骤。

1 个答案:

答案 0 :(得分:5)

此问题已在React Document中进行了描述:

componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}
  

您可以在componentDidUpdate()中立即调用setState(),但请注意   必须将其包装在上面示例中所示的条件下,或者   您将导致无限循环。

有关更多信息:componentDidUpdate()

此外,为了比较prevProps和currentProps,您可能需要考虑Object Comparison in Javascript

有几种方法可以比较javascript中的两个对象。例如:

1)快速而有限的方法

当您具有简单的JSON样式的对象而内部没有方法和DOM节点时可以使用:

JSON.stringify(obj1) === JSON.stringify(obj2)

属性的ORDER重要,因此此方法将为以下对象返回false:

 x = {a: 1, b: 2};
 y = {b: 2, a: 1};

此示例摘自:Object comparison in JavaScript