jtwang7 / React-Note

React 学习笔记
8 stars 2 forks source link

React - 合成事件 #41

Open jtwang7 opened 2 years ago

jtwang7 commented 2 years ago

React - 合成事件

参考文章:「react进阶」一文吃透react事件系统原理

三个阶段:

✅ 事件合成阶段 构建初始化React合成事件和原生事件的对应关系,合成事件和对应的事件处理插件关系。

✅ 事件绑定阶段

  1. 在 react diff 阶段,若发现对应 fiber 的 props 是React合成事件,比如 onClick,会按照事件系统逻辑单独处理。
  2. 根据React合成事件类型,找到对应的原生事件的类型(一个合成事件类型可能由多个原生事件类型共同组成,如onChange)。大部分事件都按照冒泡逻辑处理,少数事件会按照捕获逻辑处理(比如scroll事件)。
  3. 调用 addTrappedEventListener 进行真正的事件绑定,绑定在 document (React v16)上,dispatchEvent 为统一的事件处理函数。 有一点值得注意: 只有上述那几个特殊事件比如 scorll,focus,blur等是在事件捕获阶段发生的,其他的都是在事件冒泡阶段发生的,无论是onClick还是onClickCapture都是发生在冒泡阶段。

✅ 事件触发阶段 执行统一的事件处理函数 dispatchEvent,执行包含以下步骤:

  1. 首先进行的是批量更新 batchUpdate (对应 setState 的批量更新机制);
  2. 然后会执行事件对应的处理插件中的核心 extractEvents 函数;
  3. 最后通过 runEventsInBatch 执行事件队列,如果发现阻止冒泡,那么break跳出循环,最后重置事件源,放回到事件池中,完成整个流程。

extractEvents 作用:

  1. 首先形成 React 事件独有的合成事件源对象,这个对象,保存了整个事件的信息。将作为参数传递给真正的事件处理函数 handerClick。
  2. 然后声明事件执行队列 ,按照冒泡和捕获逻辑,从触发事件的位置(事件源)开始逐渐向上,查找 dom 元素类型 HostComponent 对应的 fiber ,收集上面的 React 合成事件,例如 onClick / onClickCapture ,对于冒泡阶段的事件(onClick),将 push 到执行队列后面 , 对于捕获阶段的事件(onClickCapture),将 unShift到执行队列的前面。 [React 就是用这个队列,来模拟事件捕获->事件源->事件冒泡这一过程。]
  3. 最后将事件执行队列,保存到 React 的合成事件源对象上。等待执行。