React什么时候创建SyntheticEvents?

Fau*_* NA 10 reactjs

现在,这是我理解React中事件处理的方式:

  1. 发生本机事件捕获阶段
  2. 本机事件达到目标
  3. 原生事件泡沫备份
  4. React在document图层捕获它
  5. React将它放入其中 EventPluginHub
  6. React模拟另一个完整的捕获/泡沫往返 SyntheticEvent
  7. React运行您在代码中构建的处理程序

如果我对React内部的理解是正确的,并考虑到HTML规范的这一部分:

将事件对象分派给事件目标.但是在发送开始之前,必须首先确定事件对象的传播路径.

React会等到事件冒泡document到创建它SyntheticEvent吗?如果是这样,为什么?在事件生命的第一步中,有关其传播路径的所有信息都是已知的,因此他们可以在那里完成.

Fau*_* NA 1

React 源代码中没有提及等待事件冒泡以调度SyntheticEvents 的原因(我可以找到)。

在将冒泡的事件捕获到 React 事件系统之前,决定等待冒泡的事件完成冒泡,这显然只是代码组织的问题

阅读 React 的ReactBrowserEventEmitter listenTo函数,这里进行了简化以使其更容易理解:

for (let i = 0; i < dependencies.length; i++) {
  const dependency = dependencies[i];
  switch (dependency) {

    case: // All event types that do NOT bubble
      trapCapturedEvent(dependency, mountAt);

    default:
      // By default, listen on the top level to all non-media events.
      // Media events don't bubble so adding the listener wouldn't do anything.
      const isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1;
      if (!isMediaEvent) {
        trapBubbledEvent(dependency, mountAt);
      }
      break;

  }
  isListening[dependency] = true;
}
Run Code Online (Sandbox Code Playgroud)

将冒泡事件与不冒泡事件分开(并保持代码可读)的最简单方法似乎是捕获在冒泡阶段冒泡的事件和在捕获阶段不冒泡的事件。

因此,总而言之,事件的实际工作方式(与我在问题中的最初命题进行类比)如下:

对于冒泡的事件:

  1. 本机事件捕获阶段发生
  2. 原生事件达到目标
  3. 本机事件冒泡备份
  4. React 在文档层用(抽象版本)捕获它addEventListener(type, handler, false) // False stands for "catch it in the bubbling phase"
  5. React 将其放入ReactBrowserEventEmitter
  6. React 模拟 SyntheticEvent 的另一个完整捕获/气泡往返
  7. React 运行您在代码中构建的处理程序

对于不冒泡的事件:

  1. 本机事件捕获阶段发生
  2. React 在您在代码中设置侦听器的层捕获它(抽象版本)addEventListener(type, handler, true) // True stands for "catch it in the capture phase"
  3. React 将其放入ReactBrowserEventEmitter
  4. React 模拟 SyntheticEvent 的另一个完整捕获/气泡往返
  5. React 运行您在代码中构建的处理程序