React中setState的原理,是异步的还是同步的

1、首先调用 setState 入口函数,入口函在这里就是重登一个分发器的角色,根据参数的不同,将其分发到不同的功能函数中去

ReactComponent.prototype.setState = function (partialState, callback) {
  this.updater.enqueueSetState(this, partialState);
  if (callback) {
    this.updater.enqueueCallback(this, callback, 'setState');
  }
};

2、enqueueSetState 方法将新的 state 放进组件的状态队列里,并调用 enqueueUpdate 来处理将要更新的实例对象。

enqueueSetState: function (publicInstance, partialState) {
  // 根据 this 拿到对应的组件实例
  var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState');
  // 这个 queue 对应的就是一个组件实例的 state 数组
  var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []);
  queue.push(partialState);
  //  enqueueUpdate 用来处理当前的组件实例
  enqueueUpdate(internalInstance);
}

3、在 enqueueUpdate 方法中引出了一个关键的对象 —— batchingStrategy,该对象所具备的 isBatchingUpdates 属性直接决定了当下要走更新流程,还是应该排队等待;如果轮到执行,就调用  batchedUpdates 方法来直接发起更新流程。由此可以推测出,batchingStrategy 或许正是 React 内部专门用于管控批量更新的对象。

function enqueueUpdate(component) {
  ensureInjected();
  // 注意这一句是问题的关键,isBatchingUpdates标识着当前是否处于批量创建/更新组件的阶段
  if (!batchingStrategy.isBatchingUpdates) {
    // 若当前没有处于批量创建/更新组件的阶段,则立即更新组件
    batchingStrategy.batchedUpdates(enqueueUpdate, component);
    return;
  }
  // 否则,先把组件塞入 dirtyComponents 队列里,让它“再等等”
  dirtyComponents.push(component);
  if (component._updateBatchNumber == null) {
    component._updateBatchNumber = updateBatchNumber + 1;
  }
}

 setState是异步的还是同步的?

setState 并没有异步的说法,之所以会有一种异步方法的表现形式,归根结底还是因为 react 框架本身的性能机制所导致的。在 react 的生周期函数或者作用域下为异步,在原生的环境下为同步。

因为每次调用 setState 都会触发更新,异步操作是为了提高性能,将多个状态合并一起更新,减少 render 调用。

React 会将多个 setState 的调用合并为一个来执行,也就是说,当执行setState 的时候,state专用的数据不会马上更新。

一般认为,做异步设计是为了性能优化、减少渲染次数。如果每次调用 setState 都进行一次更新,那么意味着 render 函数会被频繁调用,界面重新渲染,这样效率很低,最好的办法是获取到多个更新后进行批量更新。

在开发工作中,我们可能需要同步获取到更新之后的数据,有三种常用的方法:

1、回调函数

setState 提供了一个回调函数供开发者使用,在回调函数中,我们可以实时的获取到更新之后的数据。

2、setTimeout

图标为 setState 本身并不是异步方法,其之所以会表现出异步的形式,是因为 react 框架中本身的一个性能优化机制。所以我们使用 setTimeout 越过 react 的机制,就可以令 setState 以同步的形式体现了

3、原生事件中修改状态

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值