• 通俗易懂的React事件系统工作原理


    前言

    React 为我们提供了一套虚拟的事件系统,这套虚拟事件系统是如何工作的,笔者对源码做了一次梳理,整理了下面的文档供大家参考。

    在 React事件介绍 中介绍了合成事件对象以及为什么提供合成事件对象,主要原因是因为 React 想实现一个全浏览器的框架, 为了实现这种目标就需要提供全浏览器一致性的事件系统,以此抹平不同浏览器的差异。

    合成事件对象很有意思,一开始听名字会觉得很奇怪,看到英文名更奇怪 SyntheticEvent, 实际上合成事件的意思就是使用原生事件合成一个 React 事件, 例如使用原生click事件合成了onClick事件,使用原生mouseout事件合成了onMouseLeave事件,原生事件和合成事件类型大部分都是一一对应,只有涉及到兼容性问题时我们才需要使用不对应的事件合成。合成事件并不是 React 的首创,在 iOS 上遇到的 300ms 问题而引入的 fastclick 就使用了 touch 事件合成了 click 事件,也算一种合成事件的应用。

    了解了 React 事件是合成事件之后我们看待事件的角度就会有所不同, 例如我们经常在代码中写的这种代码

    <button onClick={
           handleClick}>
      Activate Lasers
    button>
    
    • 1
    • 2
    • 3
    • 4

    我们已经知道这个onClick只是一个合成事件而不是原生事件, 那这段时间究竟发生了什么? 原生事件和合成事件是如何对应起来的?

    上面的代码看起来很简洁,实际上 React 事件系统工作机制比起上面要复杂的多,脏活累活全都在底层处理了, 简直框架劳模。其工作原理大体上分为两个阶段

    1. 事件绑定
    2. 事件触发

    下面就一起来看下这两个阶段究竟是如何工作的, 这里主要从源码层分析,并以 16.13 源码中内容为基准。

    1. React 是如何绑定事件的 ?

    React 既然提供了合成事件,就需要知道合成事件与原生事件是如何对应起来的,这个对应关系存放在 React 事件插件中EventPlugin, 事件插件可以认为是 React 将不同的合成事件处理函数封装成了一个模块,每个模块只处理自己对应的合成事件,这样不同类型的事件种类就可以在代码上解耦,例如针对onChange事件有一个单独的LegacyChangeEventPlugin插件来处理,针对onMouseEnteronMouseLeave 使用 LegacyEnterLeaveEventPlugin 插件来处理。

    为了知道合成事件与原生事件的对应关系,React 在一开始就将事件插件全部加载进来, 这部分逻辑在 ReactDOMClientInjection 代码如下

    injectEventPluginsByName({
       
        SimpleEventPlugin: LegacySimpleEventPlugin,
        EnterLeaveEventPlugin: LegacyEnterLeaveEventPlugin,
        ChangeEventPlugin: LegacyChangeEventPlugin,
        SelectEventPlugin: LegacySelectEventPlugin,
        BeforeInputEventPlugin: LegacyBeforeInputEventPlugin
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注册完上述插件后, EventPluginRegistry (老版本代码里这个模块唤作EventPluginHub)这个模块里就初始化好了一些全局对象,有几个对象比较重要,可以单独说一下。

    第一个对象是 registrationNameModule, 它包含了 React 事件到它对应的 plugin 的映射, 大致长下面这样,它包含了 React 所支持的所有事件类型,这个对象最大的作用是判断一个组件的 prop 是否是事件类型,这在处理原生组件的 props 时候将会用到,如果一个 prop 在这个对象中才会被当做事件处理。

    {
       
        onBlur: SimpleEventPlugin,
        onClick: SimpleEventPlugin,
        onClickCapture: SimpleEventPlugin,
        onChange: ChangeEventPlugin,
        onChangeCapture: ChangeEventPlugin,
        onMo
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    yaml文件格式说明及编写教程
    【知识网络分析】作者合作网络(Co-authorship)
    ASP.NET MVC企业级程序设计 (入住退房,删除)
    信息系统项目管理师(第四版)教材精读思维导图-第十二章项目质量管理
    工业设计:产品配色与产品形态的关系
    全球No.1集装箱人工智能企业CIMCAI中集飞瞳,集装箱信息识别铅封号识别API免费,集装箱识别率99.98%高泛化性,全球两千+企业用户使用
    因学校要求寻找数据库
    Android菜单Menu详解
    基于微信共享充电桩小程序毕业设计作品成品(3)开发技术文档_充电桩小程序前端技术栈
    跑通Kaldi中的例子LibriSpeech
  • 原文地址:https://blog.csdn.net/grooyo/article/details/127878141