React之this.setState使用需知注意点 -this.setState为什么不同步更新?

this.setState为什么不同步更新?

想要了解这个话题,只需要弄清楚下面三个问题,就明明白白了

1 this.setState()本身是同步的还是不同步的?

首先明确一点,setState 其实本身执行的过程和代码都是同步的

2 是什么造成了this.setState()的不同步?

React的批处理更新(batch the updates)。
React为了优化性能,setState()执行时会判断变量isBatchingUpdates的值是true or false, 然后决定是同步更新还是批量更新(从isBatchingUpdates这个变量名就可以直观的看出)
setState不同步原理

3 那this.setState()什么时候同步,什么时候不同步?

由于isBatchingUpdates默认值是false,即默认是不批量更新的,是立即执行的,是同步的。

但如果this.setState在React合成事件/钩子函数中,React会通过batchedUpdates()这个函数将isBatchingUpdates变成true,即批量更新的,不同步的。
在这里插入图片描述
所以主要看调用this.setState()的函数有没有被React包装过,如果没经过React包装(not managed by ReactJS), isBatchingUpdates就不会从false变为true,就是同步更新的(这是我自己白话总结的,大概这个意思,可能表达不是很准确=.=)

举个栗子

分别用两种方法绑定button的click事件,点击button的时候,改变state的值

改变state的方法是同样的, 封装为changeState:

constructor(props) {
    super(props);
    this.state = {
      type: 'origin', // 原始值为 origin
    };
  }
  
changeState = e => {
    console.log('prev state:', this.state.type);
    
    this.setState({
      type: 'changed', // 改变后为 changed
    });
    
    console.log('current state:', this.state.type);
  };
a. 通过React合成事件onClick
render() {
	console.log('render');
    return (
      <Button onClick={this.changeState}>改变state</Button>
    );
  }

点击按钮,控制台打印结果:
在这里插入图片描述
说明不是同步更新的
(在输出 current state的地方,this.setState()并未执行,之后执行了才render)

b. 通过原生onclick事件
componentDidMount = e => {
    const dom = document.getElementById('btn');
    dom.addEventListener('click', this.changeState);
}

render() {
	console.log('render');
    return (
      <Button id="btn">改变state</Button>
    );
  }

控制台打印结果:
在这里插入图片描述
说明是同步更新的
(在输出prev state 之后,遇到this.setState()就立即执行了,state更新之后就触发了render,然后才输出current state)


觉得有用请点赞!
觉得有问题请留言~

这部分主要参考了这两篇文章:
setstate-state-mutation-operation-may-be-synchronous-in-reactjs
React中setState 什么时候是同步的,什么时候是异步的?

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值