1 / 16
文档名称:

React源码分析6 — React合成事件系统.docx

格式:docx   大小:412KB   页数:16页
下载后只包含 1 个 DOCX 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

React源码分析6 — React合成事件系统.docx

上传人:aena45 2018/9/23 文件大小:412 KB

下载得到文件列表

React源码分析6 — React合成事件系统.docx

相关文档

文档介绍

文档介绍:React源码分析6 — React合成事件系统
本文章来自于阿里云云栖社区
摘要: React源码系列文章,请多支持: [React源码分析1 —组件和对象的创建(createClass,createElement)](https://icles/72905) [React源码分析2 — React组件插入DOM流程](http://www.
React源码系列文章,请多支持:
React源码分析1 —组件和对象的创建(createClass,createElement)
React源码分析2 — React组件插入DOM流程
React源码分析3 — React生命周期详解
React源码分析4 — setState机制
React源码分析5 -- 组件通信,refs,key,ReactDOM
React源码分析6 — React合成事件系统
1 React合成事件特点
React自己实现了一套高效的事件注册,存储,分发和重用逻辑,在DOM事件体系基础上做了很大改进,减少了内存消耗,简化了事件逻辑,并最大化的解决了IE等浏览器的不兼容问题。与DOM事件体系相比,它有如下特点
React组件上声明的事件最终绑定到了document这个DOM节点上,而不是React组件对应的DOM节点。故只有document这个节点上面才绑定了DOM原生事件,其他节点没有绑定事件。这样简化了DOM原生事件,减少了内存开销
React以队列的方式,从触发事件的组件向父组件回溯,调用它们在JSX中声明的callback。也就是React自身实现了一套事件冒泡机制。()来停止事件传播,()
React有一套自己的合成事件SyntheticEvent,不同类型的事件会构造不同的SyntheticEvent
React使用对象池来管理合成事件对象的创建和销毁,这样减少了垃圾的生成和新对象内存的分配,大大提高了性能
那么这些特性是如何实现的呢,下面和大家一起一探究竟。
2 React事件系统
先看Facebook给出的React事件系统框图
浏览器事件(如用户点击了某个button)触发后,DOM将event传给ReactEventListener,它将事件分发到当前组件及以上的父组件。然后由ReactEventEmitter对每个组件进行事件的执行,先构造React合成事件,然后以queue的方式调用JSX中声明的callback进行事件回调。
涉及到的主要类如下
ReactEventListener:负责事件注册和事件分发。React将DOM事件全都注册到document这个节点上,这个我们在事件注册小节详细讲。事件分发主要调用dispatchEvent进行,从事件触发组件开始,向父元素遍历。我们在事件执行小节详细讲。
ReactEventEmitter:负责每个组件上事件的执行。
EventPluginHub:负责事件的存储,合成事件以对象池的方式实现创建和销毁,大大提高了性能。
SimpleEventPlugin等plugin:根据不同的事件类型,构造不同的合成事件。如focus对应的React合成事件为SyntheticFocusEvent
2 事件注册
JSX中声明一个React事件十分简单,比如
render() {
return (
<div onClick = {
(event) => {((event))}
}
/>
);
}
那么它是如何被注册到React事件系统中的呢?
ponent说起。在这两个方法中,都会调用到_updateDOMProperties方法,对JSX中声明的组件属性进行处理。源码如下
_updateDOMProperties: function (lastProps, nextProps, transaction) {
... // 前面代码太长,省略一部分
else if ((propKey)) {
// 如果是props这个对象直接声明的属性,而不是从原型链中继承而来的,则处理它
// nextProp表示要创建或者更新的属性,而lastProp则表示上一次的属性
// ponent,lastProp为null。ponent二者都不为null。ponent则nextProp为null
if (nextProp) {
// ponent中,enqueuePutListene