合成事件SyntheticEvent采用了事件池,合成事件会被放进事件池中统一管理,这样能够减少内存开销。React通过合成事件,模拟捕获和冒泡阶段,从而达到不同浏览器兼容的目的。
- react并不是将事件绑定到div的真实dom上,而是冒泡到document上面,document上绑定的统一事件处理程序会将事件分发到具体的组件实例上面。访问dom原生事件,用e.nativeEvent。
合成事件的实现机制
React 底层,主要对合成事件做了两件事:事件委派和自动绑定。
事件委派
- React 它并不会把事件处理函数直接绑定到真实的节点上,而是把所有事件绑定到结构的最外层(react16之前是document,之后是root),使用一个统一的事件监听器。
- 这个事件监听器上维持了一个映射来保存所有组件内部的事件监听和处理函数。
- 当组件挂载或卸载时,只是在这个统一的事件监听器上插入或删除一些对象;
- 当事件发生时,首先被这个统一的事件监听器处理,然后在映射里找到真正的事件处理函数并调用。
自动绑定
- 在 React 组件中,每个方法的上下文都会指向该组件的实例,即自动绑定 this 为当前组件。
- React 会对这种引用进行缓存,以达到 CPU 和内存的最优化。
- 在使用 ES6 classes 或者纯函数时,需要手动实现 this 的绑定。
合成事件和原生事件的区别
- 事件名称命名方式不同:原生事件是纯小写(例onclick),合成事件是驼峰命名(onClick)
- 事件绑定的写法有差异
clickbtn=()=>{console.log("点击按钮")}
//原生事件
<button onClick="clickbtn()"></button>
//合成事件
<button onClick={clickbtn}></button>
- 阻止默认行为方式不同。原生事件用 return false,合成事件使用e.preventDefault()。
注意点
原生事件阻止冒泡会阻止合成事件的触发,合成事件阻止冒泡不会影响原生事件。