深度分析React源码中的合成事件

热身准备

明确几个概念

[email protected]版本中:

  • 所有事件都是委托在id = root的DOM元素中(网上很多说是在document中,17版本不是了);
  • 在应用中所有节点的事件监听其实都是在id = root的DOM元素中触发;
  • React自身实现了一套事件冒泡捕获机制;
  • React实现了合成事件SyntheticEvent
  • React17版本不再使用事件池了(网上很多说使用了对象池来管理合成事件对象的创建销毁,那是16版本及之前);
  • 事件一旦在id = root的DOM元素中委托,其实是一直在触发的,只是没有绑定对应的回调函数;

image.png 盗用一张官方图,按官方解释,之所以会将事件委托从document中移到id = root的DOM元素,是为了可以更加安全地进行新旧版本 React 树的嵌套

感兴趣的可以访问:React中文网站 。

事件系统角色划分

  • 事件注册:registerEvents
  • 事件监听:listenToAllSupportedEvents
  • 事件合成:SyntheticBaseEvent
  • 事件派发:dispatchEvent

事件注册

事件注册是自执行的,也就是React自身进行调用的:

// 注册React事件
registerSimpleEvents();  
registerEvents$2();
registerEvents$1();
registerEvents$3();
registerEvents();

React事件就是在组件中调用的onClick这种写法的事件。上面分为5个函数写,主要是区分不同的事件注册逻辑,但是最后都会添加到allNativeEventsSet数据结构中

registerSimpleEvents

这里会注册大部分事件,它们在React被定义为顶级事件。

它们分为三类:

  • 离散事件:discreteEvent,常见的如:click, keyup, change
  • 用户阻塞事件:userBlocking,常见的如:dragEnter, mouseMove, scroll
  • 连续事件:continuous,常见的如:error, progress, load,
    它们的优先级排序:

0:离散事件, 1:用户阻塞事件, 2:连续事件

它们会注册冒泡和捕获阶段两个事件。

registerEvents$2

注册类似onMouseEnteronMouseLeave单阶段事件,只注册冒泡阶段事件。

registerEvents$1

注册onChange相关事件,注册冒泡和捕获阶段两个事件。

registerEvents$3

注册onSelect相关事件,注册冒泡和捕获阶段两个事件。

registerEvents

注册onBeforeInputonCompositionUpdate等相关事件,注册冒泡和捕获阶段两个事件。

事件监听

在React源码系列之二:React的渲染机制曾提到过,React在开始渲染前,会为应用创建一个fiberRoot作为应用的根节点。在创建fiberRoot还会做一件事,就是

listenToAllSupportedEvents(rootContainerElement);

从字面就能理解这个函数是做事件监听的,其中rootContainerElement参数就是应用中的id = root的DOM元素。相关参考视频讲解:进入学习

该函数主要遍历上面事件注册添加到allNativeEvents的事件,按照一定规则,区分冒泡阶段,捕获阶段,区分有无副作用进行监听,监听的api还是addEventListener:

// 监听冒泡阶段事件
function addEventBubbleListener(target, eventType, listener) {
   
  target.addEventListener(eventType, listener, false);
  return listener;
}
// 监听捕获阶段事件
function addEventCaptureListener(target, eventType, listener
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值