React 事件机制

  1. react自身实现了一套自己的事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等
  2. react 的所有事件并没有绑定到具体的dom节点上而是绑定在了document 上 (React 17 之后是绑定在 #root 节点上),然后由统一的事件处理程序来处理,同时也是基于浏览器的事件机制(冒泡),所有节点的事件都会在 document 上触发。
  3. React 根据W3C规定来定义自己的系统,其事件被称之为 合成事件(SyntheticEvent).
  4. 自定义事件的动机:
    • 抹平不同浏览器之间的兼容性差异。【主要动机】
    • 事件合成,即事件自定义。 事件合成机可以处理兼容性问题,也可以用来自定义事件。
    • 提供一个抽象跨平台机制。类似 Virtual DOM 抽象了跨平台的渲染方式,合成事件提供了一个抽象的跨平台事件机制。
    • 可以做更多的优化。例如 利用 事件委托机制,几乎所有事件的触发都代理到了document。
    • 可以干预事件的分发。V16 引入 Fiber 架构,React 可以通过干预事件的芬达来优化用户的交互体验
  5. 原生事件阻止冒泡肯定会阻止合成事件的触发。合成事件的阻止冒泡不会影响原生事件。

    • 原生事件是被绑定在目标元素本身的,其执行是在 目标阶段执行。
    • 合成事件的触发是基于浏览器的事件机制来实现的,通过冒泡机制冒泡到最顶层元素,然后再由 dispatchEvent 统一去处理。 其执行是在 冒泡阶段
    • 因此如果原生事件阻止了冒泡,那么就不会有之后 合成事件的执行了。
  6. React 拿到将要挂载的组件的虚拟 dom,然后处理react dom 的 props ,判断属性内是否声明事件的属性,比如onClick,onChange, 得到事件类型 click,change 和 对应的事件处理程序后,执行后面3步
    • 完成 事件注册【组件挂载阶段,根据组件内的声明的事件类型-onclick,onchange 等,给 document 上添加事件 -addEventListener,并指定统一的事件处理程序 dispatchEvent】 
    • react dom ,事件类型,处理函数 fn 放入数组存储
    • 组件挂载完成后,处理 b 步骤生成的数组,经过遍历把事件处理函数存储到 listenerBank 中【所有事件统一的存放到一个对象里,缓存起来,为了在触发事件的时候可以查找到对应的方法去执行
  7. react 里所有事件的触发都是通过 dispatchEvent方法统一进行派发的,而不是在注册的时候直接注册声明的回调。React 把所有的事件和事件类型以及react 组件进行关联,把这个关系保存在了一个 map里,也就是一个对象里(键值对),然后在事件触发的时候去根据当前的组件id事件类型查找到对应的事件fn
原文地址:https://www.cnblogs.com/Lyh1997/p/14807612.html