3

我有一个问题,即 setState 被各种子组件同时调用

这是一些过于简单的代码:

var Content = React.createClass({
  updateElements: function(element) {
    elements = [].concat(this.state.elements)
    elements.push(element)
    this.setState({ elements })
  }

  render: function() {
    elements = ["a", "b"];

    return (
      <div>
        <Element updateElements={this.updateElements} data={elements[0]} />
        <Element updateElements={this.updateElements} data={elements[1]} />
      </div>
    );
  }
});

var Element = React.createClass({
  componentDidMount: function() {
     this.props.updateElements(this.props.data)
  }

  render: function() {
    return (
      <div>
         {this.props.data}
      </div>
    );
  }
});

ReactDOM.render(
  <Content />,
  document.getElementById('container')
);

我可以在再次更新之前以某种方式等待之前的状态设置吗?

4

2 回答 2

1

我不完全确定,但这应该可以。如果你这样做 setState 这样

this.setState((prevState, props) => {
  return {elements: [...prevState.elements, element]};
});

它不会是同步的,但它应该保留元素而不覆盖它(因为同时更新),因为它将取自 prevState。

于 2018-05-17T13:11:01.587 回答
1

根据setState 文档

这种形式的 setState() 也是异步的,同一周期内的多次调用可能会被批处理在一起

这意味着假设您有 2 个调用以下父方法的子元素:

  doSomething1(amount){
    this.setState({
      sum1: this.state.sum1 + amount
    }, () => {
      console.warn(this.state.sum1); // 1
    })
  }

两者都将记录 1,因为后续调用将覆盖同一周期中先前调用的值,因此数量只会增加一次。

相反,您应该使用更新函数形式:

  doSomething2(amount) {
    this.setState((prevState) => {
      return { sum2: prevState.sum2 + amount };
    }, () => {
      console.warn(this.state.sum2); // 2
    });
  }

活生生的例子

如果您的问题取决于状态的先前值,这可以解决您的问题。

于 2018-05-17T15:05:10.827 回答