React16源码: React中event事件系统初始化源码实现

event 事件系统初始化


1 )概述

  • react事件系统比较的复杂,它是基于dom的事件系统
  • 在dom事件系统上面进行了一个深度的封装
  • 它里面的很多实现逻辑都是自由的一套
  • 在初始化 react-dom 的源码的时候,会为react的事件系统注入 reactdom 相关的一些插件
  • 因为react事件系统,它有一个独立的模块,这个模块是一个公用性质的模块
  • 就是说它是可以给 react-dom 用,也可以给 react-native 用
  • 不同平台它们的事件系统可能会不一样,这个时候就对于不同的平台
  • 它们要去使用同一个 event 模块的时候,使用注入的方式来注入一些跟平台相关的逻辑在里面
  • 在这个模块,也是有一部分核心的内容是全平台通用的,这部分内容是react抽象出来的
  • 我们关注平台插件注入的一个流程,以及它插入之后到底做了什么事情
    • 首先要确定一个插件注入的顺序
      • 因为在react当中它的插件执行是会按照顺序来的
      • 如果不按顺序来,可能会出现一定的问题
    • 然后要注入插件模块
    • 最后要计算 registationNameModules 等属性
  • 在之前 completeWork 的时候,初始化 dom 节点的时候
    • 要去绑定 props 对应的 dom 的 attributes 的时候
    • 就有遇到过这个 registationNameModules 属性

2 )源码

定位到 packages/react-dom/src/client/ReactDOM.js#L20

import './ReactDOMClientInjection';

再次定位到 packages/react-dom/src/client/ReactDOMClientInjection.js

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import * as EventPluginHub from 'events/EventPluginHub';
import * as EventPluginUtils from 'events/EventPluginUtils';

import {
   
  getFiberCurrentPropsFromNode,
  getInstanceFromNode,
  getNodeFromInstance,
} from './ReactDOMComponentTree';
import BeforeInputEventPlugin from '../events/BeforeInputEventPlugin';
import ChangeEventPlugin from '../events/ChangeEventPlugin';
import DOMEventPluginOrder from '../events/DOMEventPluginOrder';
import EnterLeaveEventPlugin from '../events/EnterLeaveEventPlugin';
import SelectEventPlugin from '../events/SelectEventPlugin';
import SimpleEventPlugin from '../events/SimpleEventPlugin';

/**
 * Inject modules for resolving DOM hierarchy and plugin ordering.
 */
EventPluginHub.injection.injectEventPluginOrder(DOMEventPluginOrder);
EventPluginUtils.setComponentTree(
  getFiberCurrentPropsFromNode,
  getInstanceFromNode,
  getNodeFromInstance,
);

/**
 * Some important event plugins included by default (without having to require
 * them).
 */
EventPluginHub.injection.injectEventPluginsByName({
   
  SimpleEventPlugin: SimpleEventPlugin,
  EnterLeaveEventPlugin: EnterLeaveEventPlugin,
  ChangeEventPlugin: ChangeEventPlugin,
  SelectEventPlugin: SelectEventPlugin,
  BeforeInputEventPlugin: BeforeInputEventPlugin,
});
  • 看到它 import 了一大堆的东西,后续只是调用了3个方法

    • injectEventPluginOrder
    • setComponentTree 这个先跳过
    • injectEventPluginsByName
  • 看下 EventPluginHub.injection.injectEventPluginOrder(DOMEventPluginOrder);

    • 这个 DOMEventPluginOrder
      // packages/react-dom/src/events/DOMEventPluginOrder.js
      const DOMEventPluginOrder = [
        'ResponderEventPlugin',
        'SimpleEventPlugin',
        'EnterLeaveEventPlugin',
        'ChangeEventPlugin',
        'SelectEventPlugin',
        'BeforeInputEventPlugin',
      ];
      
      export default DOMEventPluginOrder;
      
      • 它单纯的 export 出来了一个数组
      • 这个数组可以看到有6项,每一项都以一个 Plugin 为结尾的
      • 这些 plugin 都是在 react-dom 这个环境当中要用到的 plugin
      • 这边只是用来定义这些 plugin 它的一个顺序
  • 后续 EventPluginHub.injection.injectEventPluginsByName 这个方法的参数

    • 发现这里少了一个 ResponderEventPlugin 先不管
  • 关注下 EventPluginHub 这个模块下的 injection

    /**
     * Methods for injecting dependencies.
     */
    export const injection = {
         
      /**
       * @param {array} InjectedEventPluginOrder
       * @public
       */
      injectEventPluginOrder,
    
      /**
       * @param {object} injectedNamesToPlugins Map from names to plugin modules.
       */
      injectEventPluginsByName,
    };
    
    • 上述内部这两个方法来自 ./EventPluginRegistry.js 进入
      /**
       * Injects an ordering of plugins (by plugin name). This allows the ordering
      * to be decoupled from injection of the actual plugins so that ordering is
      * always deterministic regardless of packaging, on-the-fly injection, etc.
      *
      * @param {array} InjectedEventPluginOrder
      * @internal
      * @see {EventPluginHub.injection.injectEventPluginOrder}
      */
      export function injectEventPluginOrder(
        injectedEventPluginOrder: EventPluginOrder,
      ): void {
             
        invariant(
          !eventPluginOrder,
          'EventPluginRegistry: Cannot i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值