React setState updater冗余参数?

时间:2018-03-05 01:00:49

标签: reactjs react-native

this.setState((prevState, props) => ({ counter: prevState.counter + props.step }));

this.setState({ counter: this.state.counter + this.props.step });

上述两个电话的实际区别是什么?

根据React的正确用法prevStatepropsthis.statethis.props不一样?如果可能,请提供CodeSandbox等示例。

1 个答案:

答案 0 :(得分:1)

根据React文档:this.propsthis.state可能会异步更新,您不应该依赖它们的值来计算下一个状态。”
https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

详细的直觉可以在这里找到保证内部一致性
https://github.com/facebook/react/issues/11527#issuecomment-360199710

一般来说,使用this.setState({ counter: this.state.counter + this.props.step });是错误的,你应该永远不会使用它。

import React, { Component } from "react";
import { render } from "react-dom";

class App extends Component {
  state = {
    counter: 1
  };

  onClickHandler = () => {
    console.log("[onClickHandler]", this.state.counter);
    this.setState(prevState => ({
      counter: this.state.counter + 1
    }));
  };

  render() {
    return (
      <div onClick={this.onClickHandler}>
        <ChildComponent
          val={this.state.counter}
          onIncrement={() => {
            console.log("[onIncrement]");
            this.onClickHandler();
          }}
        />
      </div>
    );
  }
}

class ChildComponent extends Component {
  state = {
    counter: 0
  };

  render() {
    console.log(this.props.val);
    return (
      <h2
        onClick={() => {
          console.log("[ChildComponent]", this.props.val);
          this.props.onIncrement();
        }}
      >
        {this.props.val}
      </h2>
    );
  }
}

render(<App />, document.getElementById("root"));

考虑这个例子,预期结果应该是每次点击2次计数器更新,但它只更新一次!
prevState中使用onClickHandler可以获得预期的结果。 在CodeSandbox https://codesandbox.io/s/qkxrx06o46

上测试