本文共 1530 字,大约阅读时间需要 5 分钟。
React 并不是将 click 事件绑在该 div 的真实 DOM 上
在 document 处监听所有支持的事件,当事件发生并冒泡至 document 处时,React 将事件内容封装并交由真正的处理函数运行
不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件
冒泡到 document 上的事件也不是原生浏览器事件,而是 React 自己实现的合成事件( SyntheticEvent )
如果不想要事件冒泡的话,调用 event.stopPropagation 是无效的,而应该调用 event.preventDefault
组件装载/更新
通过 lastProps、nextProps 判断是否新增、删除事件分别调用事件注册、卸载方法
调用 EventPluginHub 的 enqueuePutListener 进行事件存储
获取 document 对象
根据事件名称(如 onClick、onCaptureClick)判断是进行冒泡还是捕获
判断是否存在 addEventListener 方法,否则使用 attchEvent(兼容 IE)
给 document 注册原生事件回调为 dispatchEvent(统一的事件分发机制)
EventPluginHub 负责管理 React 合成事件的 callback,它将 callback 存储在 listenerBank 中,另外还存储了负责合成事件的 Plugin
EventPluginHub 的 putListener 方法是向存储容器中增加一个 listener
将 callback 根据事件类型,元素的唯一标识 key 存储在 listenerBank 中
listenerBank 的结构是: listenerBank[registrationName][key]
{ onClick: { nodeid1:()=>{ ...} nodeid2:()=>{ ...} }, onChange:{ nodeid3:()=>{ ...} nodeid4:()=>{ ...}}
触发 document 注册原生事件的回调 dispatchEvent
最深一级的元素
利用了 React 的批处理机制
this.parent=ref}>this.child = ref}> test
this.child
遍历这个元素的所有父元素,依次对每一级元素进行处理
合成事件
将每一级的合成事件存储在 eventQueue 事件队列中
遍历 eventQueue
通过 isPropagationStopped 判断当前事件是否执行了阻止冒泡方法
如果阻止了冒泡,停止遍历,否则通过 executoDispatch 执行合成事件
释放处理完成的事件
调用 EventPluginHub 的 extractEvents 方法
循环所有类型的 EventPlugin(用来处理不同事件的工具方法)
在每个 EventPlugin 中根据不同的事件类型,返回不同的事件池
在事件池中取出合成事件,如果事件池是空的,那么创建一个新的
根据元素 nodeid(唯一标识 key)和事件类型从 listenerBink 中取出回调函数
返回带有合成事件参数的回调函数
转载地址:http://bjqwi.baihongyu.com/