event 对象
1 ) 概述
- 在生产事件对象的过程当中,要去调用每一个
possiblePlugin.extractEvents
方法 - 现在单独看下这里面的细节过程,即如何去生产这个事件对象的过程
2 )源码
定位到 packages/events/EventPluginHub.js#L172
function extractEvents(
topLevelType: TopLevelType,
targetInst: null | Fiber,
nativeEvent: AnyNativeEvent,
nativeEventTarget: EventTarget,
): Array<ReactSyntheticEvent> | ReactSyntheticEvent | null {
let events = null;
for (let i = 0; i < plugins.length; i++) {
// Not every plugin in the ordering may be loaded at runtime.
const possiblePlugin: PluginModule<AnyNativeEvent> = plugins[i];
if (possiblePlugin) {
// 这里要去调用 每个 plugin 的 extractEvents 方法
const extractedEvents = possiblePlugin.extractEvents(
topLevelType,
targetInst,
nativeEvent,
nativeEventTarget,
);
if (extractedEvents) {
events = accumulateInto(events, extractedEvents);
}
}
}
return events;
}
注意这里的 possiblePlugin.extractEvents
我们专门专注下 changeEvent 的这个方法
定位到 packages/react-dom/src/events/ChangeEventPlugin.js#L263
const ChangeEventPlugin = {
eventTypes: eventTypes,
_isInputEventSupported: isInputEventSupported,
// 注意这里
extractEvents: function(
topLevelType,
targetInst,
nativeEvent,
nativeEventTarget,
) {
// 在这个方法里面,拿到了 targetNode
// 因为这边传进来的呢是一个发布对象, 所以要通过这种方法拿到它的 node
const targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
// 然后,要经过一系列的判断,主要去赋值了不同的 getTargetInstFunc
let getTargetInstFunc, handleEventFunc;
// 如果有返回这个instance,那么我们就可以去创建这个event了,这是什么意思呢?
// 就是说我们这个 event plugin, 在所有的事件触发的过程当中,这个plugin都会被循环调用的
// 它是没有通过事件名称来调用不同的plugin这么一个设置的
// 所以这个判断是要放在每个pluggin里面自己去做。就是说根据这次触发的具体事件是什么?
// 来判断我们要不要为它创建一个event,因为每个plugin在每次事件触发都会被调用
// 如果我们都生成事件,那么明显是不对的,肯定要对自己这个 plugin 关心的事件来去为它生成这个事件
if (shouldUseChangeEvent(targetNode)) {
getTargetInstFunc = getTargetInstForChangeEvent;
} else if (isTextInputElement(targetNode)) {
if (isInputEventSupported) {
getTargetInstFunc = getTargetInstForInputOrChangeEvent;
} else {
// polyfill 的这些先忽略
getTargetInstFunc = getTargetInstForInputEventPolyfill;
handleEventFunc = handleEventsForInputEventPolyfill;
}
} else if (shouldUseClickEvent(targetNode)) {
getTargetInstFunc = getTargetInstForClickEvent;
}
// 基于类型,得到了最终的处理函数
if (getTargetInstFunc) {
const inst = getTargetInstFunc(topLevelType, targetInst);
if (inst) {
// 创建 event
const event = createAndAccumulateChangeEvent(
inst,
nativeEvent,
nativeEventTarget,
);
return event;
}
}
if (handleEventFunc)