export function dispatchEvent( topLevelType: DOMTopLevelEventType, nativeEvent: AnyNativeEvent, ) { if (!_enabled) { return; }
const nativeEventTarget = getEventTarget(nativeEvent); // 找到 event.target 触发事件的元素 let targetInst = getClosestInstanceFromNode(nativeEventTarget); // 找到 fiber 实例 if ( targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst) ) { // If we get an event (ex: img onload) before committing that // component's mount, ignore it for now (that is, treat it as if it was an // event on a non-React tree). We might also consider queueing events and // dispatching them after the mount. targetInst = null; } // 复用 bookKeeping,保存了事件触发的相关实例信息 const bookKeeping = getTopLevelCallbackBookKeeping( topLevelType, nativeEvent, targetInst, );
try { // Event queue being processed in the same cycle allows // `preventDefault`. batchedUpdates(handleTopLevel, bookKeeping); // 批量处理的方式进行分发 } finally { releaseTopLevelCallbackBookKeeping(bookKeeping); // 推入 pool } }
/** * Dispatches an event and releases it back into the pool, unless persistent. * dispatch 事件并将其释放回池中,除非是持久的。 * @param {?object} event Synthetic event to be dispatched. * @param {boolean} simulated If the event is simulated (changes exn behavior) * @private */ const executeDispatchesAndRelease = function( event: ReactSyntheticEvent, simulated: boolean, ) { if (event) { executeDispatchesInOrder(event, simulated); // 如果合成事件没有 persist , 才推入到 eventPool 中进行复用 if (!event.isPersistent()) { event.constructor.release(event); } } };