React 事件机制

react 并不会在该DOM元素上直接绑定事件处理器,而是实现了一套自己的事件机制,包括事件注册、事件的合成、事件执行。

自定义事件机制的动机:

  1. 抹平浏览器间的兼容性差异
  2. 改造原生事件,添加自定义属性
  3. 抽象事件机制实现跨平台开发
  4. 干预事件的分发以做到更好的优化

事件注册

事件注册做了两件事:事件注册、事件存储,完整的过程如下:

  1. 拿到需要被挂载的组件,调用 createElement 得到虚拟 DOM 树;

  2. 在虚拟 DOM 进行挂载、更新时,对组件的 props 进行处理,获取事件类型和回调函数;

  3. 挂载完成后,判断是否含有事件,如果有则在 document 上完成事件注册,并存储回调函数至 listenerBank 中;

V17 的改动

react v17 将不再往 document 上挂事件委托,而是挂载到 root DOM 上,主要是为了:

  1. 脱离 document 更方便于跨平台开发

  2. 解决多个 React 版本共存出现问题

  3. 合成事件的阻止冒泡现在会影响到手动添加的 DOM 事件的触发,因为 root DOM 会比 document 先一步接收到事件的冒泡:

    document.addEventListener('click', function() {
      // This custom handler will no longer receive clicks
      // from React components that called e.stopPropagation()
    });
    

事件合成

合成事件包括:对原生事件的封装、对原生事件的改造、对不同浏览器的兼容。

封装原生事件

合成事件的回调函数会接收到 SyntheticEvent 的实例,实例拥有和浏览器原生事件一样的接口,原生的浏览器事件可以通过 nativeEvent 属性来获得

67

改造原生事件

react并不是只处理你声明的事件类型,还会额外的增加一些其他的事件,帮助我们提升交互的体验。

例如在绑定 onChange 事件后,react 会在 SyntheticEvent 实例中额外注册 invalid 事件。

兼容浏览器

例如 react 在绑定事件方面对 ie8 及早期版本进行兼容,使用 target.attachEvent()替换target.addEventListener()

事件执行

事件执行的主要步骤:

  1. 事件冒泡到 document;
  2. 执行统一的事件分发函数 dispatchEvent;
  3. 找到当前事件对应的 ReactDOMComponent 对象;
  4. 进行事件的合成;
  5. 批量处理合成事件内的回调事件;
作者

BiteByte

发布于

2020-09-10

更新于

2024-11-15

许可协议