返回
React事件源码剖析,掌握事件机制的精髓
前端
2023-12-27 12:28:56
React 作为一款流行的前端框架,其事件系统的设计也十分精妙。本文将带领大家深入剖析 React 事件的源码,以期大家对事件机制有更深入的理解。文章将分为三个部分:事件绑定、事件触发及收集、回调函数执行。
事件绑定
React 事件的绑定主要通过 addEventListener()
方法实现。在 React 的源码中,addEventListener()
方法被封装在了 DOMEventListener
类中,该类提供了统一的事件绑定接口。
class DOMEventListener {
constructor(target, eventType, callback) {
this.target = target;
this.eventType = eventType;
this.callback = callback;
this.handleEvent = this.handleEvent.bind(this);
}
handleEvent(event) {
this.callback(event);
}
remove() {
this.target.removeEventListener(this.eventType, this.handleEvent);
}
}
当我们使用 React 的 onClick
、onMouseMove
等事件处理函数时,实际上就是调用了 addEventListener()
方法,将事件监听器绑定到了对应的 DOM 元素上。
事件触发及收集
当事件被触发时,浏览器会生成一个事件对象,并将该事件对象传递给事件监听器。在 React 中,事件对象会被封装成一个合成事件对象,该对象包含了事件类型、目标元素、事件数据等信息。
class SyntheticEvent {
constructor(event) {
this.type = event.type;
this.target = event.target;
this.data = event.data;
}
}
合成事件对象会被收集到一个事件队列中,然后由事件循环统一处理。
const eventQueue = [];
function handleEvent() {
while (eventQueue.length > 0) {
const event = eventQueue.shift();
event.target.dispatchEvent(event);
}
}
addEventListener("click", handleEvent);
回调函数执行
当事件被分发到目标元素时,事件监听器中的回调函数就会被执行。在 React 中,回调函数的执行是在 ReactDOM
中进行的。
class ReactDOM {
static render(element, container) {
// 这里省略了其他代码
// 事件处理
const eventListeners = [];
element.props.children.forEach((child) => {
const eventListeners = child.props.eventListeners;
eventListeners.forEach((eventListener) => {
eventListener.target.addEventListener(eventListener.eventType, eventListener.handleEvent);
});
});
// 这里省略了其他代码
}
}
在 render()
函数中,React 会遍历所有子元素,并将子元素的事件监听器添加到事件队列中。当事件被分发到目标元素时,事件队列中的回调函数就会被执行。
这就是 React 事件机制的整体流程。通过对源码的剖析,我们可以更加深入地理解 React 事件是如何工作的。