• 深度分析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
  • 相关阅读:
    科赫曲线
    SLAM从入门到精通(矩阵的使用)
    开源网安入选广东省网络空间安全标准化技术委员会新技术及应用安全技术工作组成员单位
    Springboot整合Zookeeper分布式组件实例
    SpringCloudAlibaba中篇(Sentinel,Seata)(超级无敌认真好用,万字收藏篇!!!!)
    SpringBoot入门教程:数据库恢复(mysqldump和mysqlbinlog)
    MySQL性能优化-范式设计和反范式设计
    基础-MVP图像处理-仿射变换
    ssm基于Java web 的人人影视网站管理系统毕业设计源码290915
    py2neo 查询语句
  • 原文地址:https://blog.csdn.net/It_kc/article/details/127608563