React事件系统
2020 reactReact 基于 Virtual DOM 实现了一个 SyntheticEvent(合成事件)层,我们所定义的事件处理器会接收到一个 SyntheticEvent 对象的实例。所有事件都自动绑定到最外层上。如果需要访问原生事件对象,可以使用 nativeEvent 属性。
实现机制
在 React 底层,主要对合成事件做了两件事:事件委派和自动绑定。
事件委派
从 v17.0.0 开始,React 不会将事件处理添加到 document 上,而是将事件处理添加到渲染 React 树的根 DOM 容器中。
当组件挂载或卸载时,只是在这个统一的事件监听器上插入或删除一些对象;当事件发生时,首先被这个统一的事件监听器处理,然后在映射里找到真正的事件处理函数并调用。这样做简化了事件处理和回收机制,效率也有很大提升。
自动绑定
在 React 组件中,每个方法的上下文都会指向该组件的实例,即自动绑定 this 为当前组件。而且 React 还会对这种引用进行缓存,以达到 CPU 和内存的最优化。在使用 ES6 classes 或者纯函数时,这种自动绑定就不复存在了,我们需要手动实现 this 的绑定,否则 this 会被定义成 undefined。
绑定 this 的几个方法: 1. bind 方法 2. 构造器内声明 3. 箭头函数
React 合成事件与 JavaScript 原生事件
-
事件传播与阻止事件传播
DOM 事件传播有三个阶段:事件捕获阶段,目标对象的时间处理以及事件冒泡。而 React 的合成事件则没有实现事件捕获,仅仅支持事件冒泡机制。
-
事件类型
React 合成事件的事件类型是 JavaScript 原生事件类型的一个子集。
-
事件绑定方式
React 事件使用驼峰法命名,而不是小写。传递函数作为事件处理,而不是字符串。典型例子如下:
<!-- 原生 --> <button onclick="handleEvent()">Click Me</button> <!-- React --> <button onClick="{handleEvent}">Click Me</button>
-
事件对象
React 合成事件系统中,不存在兼容性问题,在事件处理函数中可以得到一个合成事件对象。
参考链接
- 《深入 React 技术栈》
- React: SyntheticEvent
- React: Handling Events
- React: v17.0