代码之家  ›  专栏  ›  技术社区  ›  Craig

使用componentDidUpdate反应无限循环

  •  3
  • Craig  · 技术社区  · 6 年前

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

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

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

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

    未捕获错误:超过最大更新深度。这可能发生在 组件在componentWillUpdate或 组件更新。React将嵌套更新的数量限制为 防止无限循环。

    我猜“componentDidUpdate”是为它们调用的,因为父级状态基本上更新了所有步骤,它们反过来通知父级状态更新了吗?

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

    1 回复  |  直到 6 年前
        1
  •  9
  •   You Nguyen    6 年前

    该问题已在React文件中描述:

    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) 快速和有限的方法

    在没有方法和DOM节点的简单JSON样式对象中工作:

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

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

    此示例取自: Object comparison in JavaScript