为什么要自己实现一套事件机制
由于fiber机制的特点,生成一个fiber节点时,它对应的dom节点有可能还未挂载,onClick这样的事件处理函数作为fiber节点的prop,也就不能直接被绑定到真实的DOM节点上。为此,React提供了一种“顶层注册,事件收集,统一触发”的事件机制。所谓“顶层注册”,其实是在root元素上绑定一个统一的事件处理函数。“事件收集”指的是事件触发时(实际上是root上的事件处理函数被执行),构造合成事件对象,按照冒泡或捕获的路径去组件中收集真正的事件处理函数。“统一触发”发生在收集过程之后,对所收集的事件逐一执行,并共享同一个合成事件对象。这里有一个重点是绑定到root上的事件监听并非我们写在组件中的事件处理函数,注意这个区别,下文会提到。以上是React事件机制的简述,这套机制规避了无法将事件直接绑定到DOM节点上的问题,并且能够很好地利用fiber树的层级关系来生成事件执行路径,进而模拟事件捕获和冒泡,另外还带来两个非常重要的特性:
对事件进行归类,可以在事件产生的任务上包含不同的优先级
提供合成事件对象,抹平浏览器的兼容性差异
本文会对事件机制进行详细讲解,贯穿一个事件从注册到被执行的生命周期。
事件注册
与之前版本不同,React17的事件是注册到root上而非document,这主要是为了渐进升级,避免多版本的React共存的场景中事件系统发生冲突。
当我们为一个元素绑定事件时,会这样写:
divonClick={()={/*dosomething*/}}React/div
这个div节点最终要对应一个fiber节点,onClick则作为它的prop。当这个fiber节点进入render阶段的