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


    热身准备

    明确几个概念

    React@17.0.3版本中:

    • 所有事件都是委托在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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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);
    
    • 1

    从字面就能理解这个函数是做事件监听的,其中rootContainerElement参数就是应用中的id = root的DOM元素。

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

    // 监听冒泡阶段事件
    function addEventBubbleListener(target, eventType, listener) {
       
      target.addEventListener(eventType, listener, false);
      return listener;
    }
    // 监听捕获阶段事件
    function addEventCaptureListener(target, eventType, listener
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    三种方法教你下载 Windows 10 和 Windows 11 原生镜像
    JVM判断对象是否存活之引用计数法、可达性分析
    2022杭电多校八 1005-Ironforge(二分+区间暴力)
    【面试精讲】深克隆和浅克隆的实现方式?深克隆和浅克隆有什么区别?
    使用水泥路肩培土两用机进行施工一次制作成型
    uniapp 省市区三级联动选择器
    React antd组件Checkbox.Group单选实现
    广州穗雅口腔黏膜专科教你:如何辨别口腔溃疡的好坏
    acwing 843. n-皇后问题
    漏洞复现-蓝凌LandrayOA系列
  • 原文地址:https://blog.csdn.net/It_kc/article/details/127781647