20190313 react基础之setState异步更新

官网中说 react setState()方法 状态更新可能是异步的

官网详情移步:https://react.docschina.org/docs/state-and-lifecycle.html

React 可以将多个setState() 调用合并成一个调用来提高性能。

因为 this.props 和 this.state 可能是异步更新的,你不应该依靠它们的值来计算下一个状态。

// Wrong 此代码`可能`无法更新计数器:
this.setState({
  counter: this.state.counter + this.props.increment,
});
// Correct
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));

React 中 setState 什么时候是同步的,什么时候是不同步的?

回答:

在React中,如果是

由React引发的事件处理(比如:onClick),调用setState不会同步更新this.state;

绕过React引发的事件处理(比如: addEventListener直接添加、setTimeout/setInterval 产生的异步调用),调用setState会同步更新this.state;

原因:

在React的setState的函数实现中,根据变量isBatchingUpdates判断是否立即更新this.state。值为false则立即更新。

在调用 由React引发的事件处理 之前,会调用batchedUpdates函数,将isBatchingUpdates的值修改为true,也就是不同步更新this.state。

观察下面代码的输出 (React setState)

class Example extends React.Component {
  constructor() {
    super();
    this.state = {
      val: 0
    };
  }
  
  componentDidMount() {
    this.setState({val: this.state.val + 1});
    console.log(this.state.val);    // 第 1 次 log ---- 0

    this.setState({val: this.state.val + 1});
    console.log(this.state.val);    // 第 2 次 log ---- 0

    setTimeout(() => {
      this.setState({val: this.state.val + 1});
      console.log(this.state.val);  // 第 3 次 log ---- 2

      this.setState({val: this.state.val + 1});
      console.log(this.state.val);  // 第 4 次 log ---- 3
    }, 0);
  }

  render() {
    return null;
  }
};
  1. 第 1 次 log, 第 2 次 log 都是在React自身的生命周期中,调用之前触发batchedUpdates函数,isBatchingUpdates为true,所以不会立即更新this.state,而是加入了脏组件

  2. 两次 setState 时,获取到 this.state.val 都是 0,所以执行时都是将 0 设置成 1,在 react 内部会被合并掉,只执行一次。设置完成后 state.val 值为 1。

  3. setTimeout时,isBatchingUpdates为false,所以会立即更新this.state。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值