Javascript 使用shouldComponetUpdate中断状态集循环?

Javascript 使用shouldComponetUpdate中断状态集循环?,javascript,reactjs,state,Javascript,Reactjs,State,我正在开发一个react应用程序,无意中发现如果我不使用shouldComponentUpdate()来挡路,我的组件就会不断地相互更新。我正在尝试决定这是处理此类更改的最佳方式,还是应该尝试重构代码,这样就不必以这种方式停止更新 我的实际代码中充满了其他正在进行的事情,所以我把几个虚拟示例放在一起 父组件: class App extends React.Component { constructor() { super(); this.s

我正在开发一个react应用程序,无意中发现如果我不使用
shouldComponentUpdate()
来挡路,我的组件就会不断地相互更新。我正在尝试决定这是处理此类更改的最佳方式,还是应该尝试重构代码,这样就不必以这种方式停止更新

我的实际代码中充满了其他正在进行的事情,所以我把几个虚拟示例放在一起

父组件:

    class App extends React.Component {
      constructor() {
        super();

        this.stateChange = this.stateChange.bind(this);

        this.state = {
          foo: 'bar'
        }
      }


      stateChange(change) {
        this.setState({foo: change});
      }

      render() {
        return (
          <div>
            <p>Hello World</p>
            <ChildComponent stateChange={this.stateChange} />
          </div>
          )
      }

    }
但我想知道的是,这是否是最佳实践,或者我是否应该提出其他解决方案。“我的孩子”组件具有状态,因为它快速连续地循环使用大约6个不同的参数,而应用程序的其余部分不必知道发生了什么,因此通过将
阶段一直返回到父级来重新启动整个应用程序是没有意义的


希望这个问题有意义。感谢阅读。

您永远不应该更改渲染状态,请选中此项。
在渲染之外做出这些状态决定和填充。

您不应该在渲染时更改状态,请选中此项。
在渲染之外做出这些状态决定和填充。

您所做的根本不正确。想想react是如何更新DOM的。只要组件的状态发生更改,就会调用组件的渲染方法

在组件中,触发函数,该函数在调用render方法时更新状态(renderDecision)。因此,当调用渲染时,状态将更新,并且由于状态已更新,因此将再次调用渲染。这迫使一个无限循环

解决方案


使用适当的生命周期方法或事件(例如onClick)更新状态。在您的情况下,您可以在componentDidMount或componentWillMount中设置状态。您所做的根本不正确。想想react是如何更新DOM的。只要组件的状态发生更改,就会调用组件的渲染方法

在组件中,触发函数,该函数在调用render方法时更新状态(renderDecision)。因此,当调用渲染时,状态将更新,并且由于状态已更新,因此将再次调用渲染。这迫使一个无限循环

解决方案


使用适当的生命周期方法或事件(例如onClick)更新状态。在您的情况下,您可以在componentDidMount或componentWillMount中设置状态!哎呀。这很有帮助,非常感谢。(在我的实际代码中,我的大多数状态更改决定都封装在用户输入上运行的函数中;还有一个不是,这就是导致我循环的函数。)哦,不!哎呀。这很有帮助,非常感谢。(在我的实际代码中,我的大多数状态更改决策都封装在用户输入上运行的函数中;还有一个不是,这就是导致我循环的函数。)
    class ChildComponent extends React.Component {
      constructor() {
        super();

        this.renderDecision = this.renderDecision.bind(this);
        this.updateStage = this.updateStage.bind(this);
        this.state = {
          stage: [1],
          hello: 'world'
        }
      }

      updateStage(e) {
          let theStage = [...this.state.stage];
          theStage.push(1);
          this.setState({stage: theStage});
        }

      renderDecision() {

        if (this.state.stage.length < 3) {
          return (
            <p>There are {this.state.stage.length} items. <button onClick={(e) => this.updateStage(e)}>Click here to update.</button></p>
            )
        } else if (this.state.stage.length === 3) {
          this.props.stateChange(this.state.hello); /// updates the parent which updates the child which updates the parent... ad infinitum
          return (
            <p>Hello {this.state.hello}, there are {theStage} items.</p>
          )
        }
      }

      render() {
        return (
          <div>
            (this.renderDecision())
          </div>
        )
      }
    }
      componentShouldUpdate() {
        if (this.state.stage.length === 3) {
          return false;
        } else return true;
      }