Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React 事件(一) 事件介绍和初始化 #36

Open
xiaoxiaosaohuo opened this issue Nov 22, 2018 · 0 comments
Open

React 事件(一) 事件介绍和初始化 #36

xiaoxiaosaohuo opened this issue Nov 22, 2018 · 0 comments

Comments

@xiaoxiaosaohuo
Copy link
Owner

React 事件概览

* Overview of React and the event system:
 *
 * +------------+    .
 * |    DOM     |    .
 * +------------+    .
 *       |           .
 *       v           .
 * +------------+    .
 * | ReactEvent |    .
 * |  Listener  |    .
 * +------------+    .                         +-----------+
 *       |           .               +--------+|SimpleEvent|
 *       |           .               |         |Plugin     |
 * +-----|------+    .               v         +-----------+
 * |     |      |    .    +--------------+                    +------------+
 * |     +-----------.--->|EventPluginHub|                    |    Event   |
 * |            |    .    |              |     +-----------+  | Propagators|
 * | ReactEvent |    .    |              |     |TapEvent   |  |------------|
 * |  Emitter   |    .    |              |<---+|Plugin     |  |other plugin|
 * |            |    .    |              |     +-----------+  |  utilities |
 * |     +-----------.--->|              |                    +------------+
 * |     |      |    .    +--------------+
 * +-----|------+    .                ^        +-----------+
 *       |           .                |        |Enter/Leave|
 *       +           .                +-------+|Plugin     |
 * +-------------+   .                         +-----------+
 * | application |   .
 * |-------------|   .
 * |             |   .
 * |             |   .
 * +-------------+   .
 *                   .
 *    React Core     .  General Purpose Event Plugin System
 */

React 事件机制特点

  1. react利用事件委托机制把浏览器原生事件都委托到document对象上,减少页面的注册事件数量,减少内存开销,优化浏览器性能,也能更好的统一管理事件。
  2. 事件处理函数将会接收SyntheticEvent的实例,一个基于浏览器原生事件的跨浏览器实现。它拥有和浏览器原生事件一样的接口,包括stopPropagation()和preventDefault()
  3. 合成事件由对应的 EventPlugin负责合成,不同类型的事件由不同的 plugin合成,例如 SimpleEvent Plugin、TapEvent Plugin等
  4. SyntheticEvent是共享的。那就意味着在调用事件回调之后,SyntheticEvent对象将会被重用,并且所有属性会被置空
  5. 所有的事件都是以一种先进先出的队列方式进行触发与回调

事件相关的全局变量

//已注册插件的有序列表。
var plugins = [];

 // event name 到dispatch config的映射

var eventNameDispatchConfigs = {};
//registration name 到 event name的映射
var registrationNameDependencies = {};
//注册名对应的插件
registrationNameModules
// 事件名对应的dispatchConfig
eventNameDispatchConfigs
//注册名对应的原生事件名
registrationNameDependencies

事件插件

事件插件可以实现以下属性

  • extractEvents 这个是必须实现的,当顶级事件触发时,此方法会提取合成事件,放入队列进行dispatch
  • eventTypes 插件要触发事件必须发布一个用于注册侦听器的注册名称映射表,是包含registrationName或者phasedRegistrationNames的对象。
  • executeDispatch 允许插件覆盖事件的调度方式,默认情况下,只调用侦听器

每个插件都要注入到EventsPluginHub

这是用于安装和配置事件插件的统一接口

var injection = {
  
  injectEventPluginOrder: injectEventPluginOrder,
//插件注入顺序
  injectEventPluginsByName: injectEventPluginsByName
  //从名称到插件模块的映射。
};  

injection.injectEventPluginOrder(DOMEventPluginOrder);

injection.injectEventPluginsByName({
  SimpleEventPlugin: SimpleEventPlugin,
  EnterLeaveEventPlugin: EnterLeaveEventPlugin,
  ChangeEventPlugin: ChangeEventPlugin,
  SelectEventPlugin: SelectEventPlugin,
  BeforeInputEventPlugin: BeforeInputEventPlugin
});

事件注入顺序

[ 
"ResponderEventPlugin",
"SimpleEventPlugin", 
"EnterLeaveEventPlugin",
"ChangeEventPlugin",
"SelectEventPlugin",
"BeforeInputEventPlugin"
]



在安装事件的过程中,会按照预定顺序重新计算,将插件装入plugins对应的位置,在这个过程中, ,并遍历当前插件的eventTypes执行
publishEventForPlugin方法。

publishEventForPlugin方法主要职责


//一下三种映射关系
//事件名对应的dispatchConfig
eventNameDispatchConfigs[eventName] = dispatchConfig;
//注册名对应的插件
registrationNameModules[registrationName] = pluginModule;
//注册名对应的原生事件名
registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
dispatchConfig


{
dependencies: ["click"]
isInteractive: true
phasedRegistrationNames:{
    bubbled: "onClick"
    captured: "onClickCapture" 
    }
}
pluginModule

pluginModule:{
    eventTypes:{
        click:{
            dependencies: ["click"]
            isInteractive: true
            phasedRegistrationNames:{
                bubbled: "onClick"
                captured: "onClickCapture"
            }
            
        }
        ....
    },
    extractEvents:f,//方法
    isInteractiveTopLevelEventType:f
}

附图 各事件插件和eventTypes的数据结构
2018-11-22 15 58 58

2018-11-22 16 05 07

React 启动之后的事件初始化就到这里结束了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant