react源码要封装合成事件优势
- 通过事件委托机制,将所有事件处理程序附加到根元素上,而不是每个子元素;提高了性能和内存使用效率,特别是在有大量元素的情况下
- 重新封装的合成事件消除了浏览器的差异,兼容性好
如何实现的
- 事件注册: 在createRoot之前就会调用
scss
// 当前React18提供了以下5个合成事件
Plugin SimpleEventPlugin.registerEvents(); // SimpleEventPlugin 处理一些常用的基础事件,详细请参见DOMEventProperties.js 中的registerSimpleEvents注册函数
EnterLeaveEventPlugin.registerEvents(); // 鼠标移动事件
ChangeEventPlugin.registerEvents(); // 修改事件
SelectEventPlugin.registerEvents(); // 处理选择事件
BeforeInputEventPlugin.registerEvents(); // 处理控件输入前事件
- 事件绑定
scss
const createRoot(rootContainerElement){
.....
// 在根元素上进行事件绑定
listenToAllSupportedEvents(rootContainerElement);
}
- 事件触发
scss
export function dispatchEvent(
domEventName: DOMEventName,
eventSystemFlags: EventSystemFlags,
targetContainer: EventTarget,
nativeEvent: AnyNativeEvent,
): void {
......
// 收集沿途事件、构建合成事件、遍历捕获事件、遍历冒泡事件
dispatchEventForPluginEventSystem(
domEventName,
eventSystemFlags,
nativeEvent,
null,
targetContainer,
);
}
function dispatchEventsForPlugins(
domEventName: DOMEventName,
eventSystemFlags: EventSystemFlags,
nativeEvent: AnyNativeEvent,
targetInst: null | Fiber,
targetContainer: EventTarget,
): void {
const nativeEventTarget = getEventTarget(nativeEvent);
// 存放事件的队列
const dispatchQueue: DispatchQueue = [];
// 收集沿途事件、构建合成事件
extractEvents(
dispatchQueue,
domEventName,
targetInst,
nativeEvent,
nativeEventTarget,
eventSystemFlags,
targetContainer,
);
// 遍历捕获事件、遍历冒泡事件
processDispatchQueue(dispatchQueue, eventSystemFlags);
}
大致流程图如下:
