React16源码: React中event事件中batchedUpdates, controlled inputs以及事件绑定dispatchEvent源码实现

本文详细解释了React中事件处理的流程,特别是batchedUpdates和interactiveUpdates的作用,以及如何确保controlledinputs的正确回调和状态同步。同时讨论了dispatchEvent和dispatchInteractiveEvent的区别及其在事件绑定中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

event中注意事项


1 )概述

  • 前面把 react 当中事件从开始注入到事件的监听
  • 到把整个事件对象给它构造出来,最后去触发这个事件的整体的流程
  • 还有一些重要的内容,补充下
    • batchedUpdates
      • 通过事件去触发的,大部分 setState 都处于 batchedUpdates 里面
      • 也就是这一部分的 setState,它们的更新都会一起被提交,最终再一起回调
      • 就是之前的举例,调用了 setState 之后,对 state 进行 console.log
      • 发现这个 state 没有立即变化,这种情况在事件当中是什么时候被设置的?
    • controlled inputs 如何回调
    • 关于事件绑定dispatchEvent

2 )源码

2.1 batchedUpdates

定位到 packages/react-dom/src/client/ReactDOM.js#L456

// 依赖注入
ReactGenericBatching.setBatchingImplementation(
  DOMRenderer.batchedUpdates,
  DOMRenderer.interactiveUpdates,
  DOMRenderer.flushInteractiveUpdates,
);

// packages/events/ReactGenericBatching.js#L63
export function setBatchingImplementation(
  batchedUpdatesImpl,
  interactiveUpdatesImpl,
  flushInteractiveUpdatesImpl,
) {
   
  _batchedUpdatesImpl = batchedUpdatesImpl;
  _interactiveUpdatesImpl = interactiveUpdatesImpl;
  _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl;
}

定位上述三个方法

// packages/react-reconciler/src/ReactFiberScheduler.js#L2440
function batchedUpdates<A, R>(fn: (a: A) => R, a: A): R {
   
  const previousIsBatchingUpdates = isBatchingUpdates;
  isBatchingUpdates = true;
  try {
   
    return fn(a);
  } finally {
   
    isBatchingUpdates = previousIsBatchingUpdates;
    if (!isBatchingUpdates && !isRendering) {
   
      performSyncWork();
    }
  }
}

// packages/react-reconciler/src/ReactFiberScheduler.js#L2485
function interactiveUpdates<A, B, R>(fn: (A, B) => R, a: A, b: B): R {
   
  if (isBatchingInteractiveUpdates) {
   
    return fn(a, b);
  }
  // If there are any pending interactive updates, synchronously flush them.
  // This needs to happen before we read any handlers, because the effect of
  // the previous event may influence which handlers are called during
  // this event.
  if (
    !isBatchingUpdates &&
    !isRendering &&
    lowestPriorityPendingInteractiveExpirationTime !== NoWork
  ) {
   
    // Synchronously flush pending interactive updates.
    performWork(lowestPriorityPendingInteractiveExpirationTime, false);
    lowestPriorityPendingInteractiveExpirationTime = NoWork;
  }
  const previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
  const previousIsBatchingUpdates = isBatchingUpdates;
  // 在开始执 fn(a, b) 之前设置 下面两个变量为 true
  // 设置这两个全局变量,不会立马就去执行后续的 performWork 操作
  isBatchingInteractiveUpdates = true;
  isBatchingUpdates = true;
  try {
   
    return fn(a, b);
  } finally {
   
    isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
    isBatchingUpdates = previousIsBatchingUpdates;
    if (!isBatchingUpdates && !isRendering) {
   
      performSyncWork();
    }
  }
}

// packages/react-reconciler/src/ReactFiberScheduler.js#L2517
function flushInteractiveUpdates() {
   
  if (
    !isRendering &&
    lowestP
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值