setState到底是异步还是同步?

一、合成事件和生命周期函数里是异步的

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      count: 0,
    };
  }
  render() {
    const { count } = this.state;
    return (
      <div>
        <h1>{count}</h1>
        <button id="add" onClick={this.btnChange}>增加</button>
      </div>
    );
  }
  btnChange = () => {
    this.setState({
      count: this.state.count + 1,
    });
    console.log("this.state.count : ", this.state.count);
  };
}

其实造成setState的异步并不是由内部的异步代码引起的,在本身的执行过程中时同步的,但是合成事件和生命周期函数的调用顺序在更新之前,导致在内部不能直接得到更新后的值。我们可以利用setState的第二个参数callback得到最新的值,代码如下:

  btnChange = () => {
    this.setState({
      count: this.state.count + 1,
    }, () => {
      //此时打印为 1
      console.log("this.state.count :>> ", this.state.count);
    });
    //此时打印为 0
    console.log("this.state.count :>> ", this.state.count);
  };

需要值得注意的是在控制台中,先打印0,后打印1。

二、在原生事件和setTimeout里是同步的

而在原生的DOM时间和setTimeout中,则表现为同步,我们将上面的点击事件做一下修改

  btnChange = () => {
    setTimeout(() => {
      this.setState({
        count: this.state.count + 1,
      });
      console.log("this.state.count :>> ", this.state.count);
    }, 0);
  };

同理在原生的DOM事件中也是一样的:

  componentDidMount() {
    document.querySelector("#add").addEventListener("click", () => {
      this.setState({
        count: this.state.count + 1,
      });
      console.log("this.state.count :>> ", this.state.count);
    });
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值