Decouple dispatching from attemptToDispatchEvent (#22851)

* Decoupled dispatching from attemptToDispatchEvent

* Remove unnecessary field

It is unnecessary because it's only true when retval is null.
This commit is contained in:
Dan Abramov
2021-12-02 13:55:57 +00:00
committed by GitHub
parent ed00d2c3d8
commit ea5a413602
2 changed files with 52 additions and 19 deletions
+26 -13
View File
@@ -180,15 +180,20 @@ export function dispatchEvent(
return;
}
let blockedOn = attemptToDispatchEvent(
let blockedOn = findInstanceBlockingEvent(
domEventName,
eventSystemFlags,
targetContainer,
nativeEvent,
);
if (blockedOn === null) {
// We successfully dispatched this event.
dispatchEventForPluginEventSystem(
domEventName,
eventSystemFlags,
nativeEvent,
return_targetInst,
targetContainer,
);
if (allowReplay) {
clearIfContinuousEvent(domEventName, nativeEvent);
}
@@ -236,12 +241,21 @@ export function dispatchEvent(
if (fiber !== null) {
attemptSynchronousHydration(fiber);
}
const nextBlockedOn = attemptToDispatchEvent(
const nextBlockedOn = findInstanceBlockingEvent(
domEventName,
eventSystemFlags,
targetContainer,
nativeEvent,
);
if (nextBlockedOn === null) {
dispatchEventForPluginEventSystem(
domEventName,
eventSystemFlags,
nativeEvent,
return_targetInst,
targetContainer,
);
}
if (nextBlockedOn === blockedOn) {
break;
}
@@ -264,8 +278,11 @@ export function dispatchEvent(
);
}
// Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked.
export function attemptToDispatchEvent(
export let return_targetInst = null;
// Returns a SuspenseInstance or Container if it's blocked.
// The return_targetInst field above is conceptually part of the return value.
export function findInstanceBlockingEvent(
domEventName: DOMEventName,
eventSystemFlags: EventSystemFlags,
targetContainer: EventTarget,
@@ -273,6 +290,8 @@ export function attemptToDispatchEvent(
): null | Container | SuspenseInstance {
// TODO: Warn if _enabled is false.
return_targetInst = null;
const nativeEventTarget = getEventTarget(nativeEvent);
let targetInst = getClosestInstanceFromNode(nativeEventTarget);
@@ -313,13 +332,7 @@ export function attemptToDispatchEvent(
}
}
}
dispatchEventForPluginEventSystem(
domEventName,
eventSystemFlags,
nativeEvent,
targetInst,
targetContainer,
);
return_targetInst = targetInst;
// We're not blocked on anything.
return null;
}
+26 -6
View File
@@ -27,7 +27,11 @@ import {
getContainerFromFiber,
getSuspenseInstanceFromFiber,
} from 'react-reconciler/src/ReactFiberTreeReflection';
import {attemptToDispatchEvent} from './ReactDOMEventListener';
import {
findInstanceBlockingEvent,
return_targetInst,
} from './ReactDOMEventListener';
import {dispatchEventForPluginEventSystem} from './DOMPluginEventSystem';
import {
getInstanceFromNode,
getClosestInstanceFromNode,
@@ -389,7 +393,7 @@ export function queueIfContinuousEvent(
function attemptExplicitHydrationTarget(
queuedTarget: QueuedHydrationTarget,
): void {
// TODO: This function shares a lot of logic with attemptToDispatchEvent.
// TODO: This function shares a lot of logic with findInstanceBlockingEvent.
// Try to unify them. It's a bit tricky since it would require two return
// values.
const targetInst = getClosestInstanceFromNode(queuedTarget.target);
@@ -462,13 +466,21 @@ function attemptReplayContinuousQueuedEvent(
const targetContainers = queuedEvent.targetContainers;
while (targetContainers.length > 0) {
const targetContainer = targetContainers[0];
const nextBlockedOn = attemptToDispatchEvent(
const nextBlockedOn = findInstanceBlockingEvent(
queuedEvent.domEventName,
queuedEvent.eventSystemFlags,
targetContainer,
queuedEvent.nativeEvent,
);
if (nextBlockedOn !== null) {
if (nextBlockedOn === null) {
dispatchEventForPluginEventSystem(
queuedEvent.domEventName,
queuedEvent.eventSystemFlags,
queuedEvent.nativeEvent,
return_targetInst,
targetContainer,
);
} else {
// We're still blocked. Try again later.
const fiber = getInstanceFromNode(nextBlockedOn);
if (fiber !== null) {
@@ -512,13 +524,21 @@ function replayUnblockedEvents() {
const targetContainers = nextDiscreteEvent.targetContainers;
while (targetContainers.length > 0) {
const targetContainer = targetContainers[0];
const nextBlockedOn = attemptToDispatchEvent(
const nextBlockedOn = findInstanceBlockingEvent(
nextDiscreteEvent.domEventName,
nextDiscreteEvent.eventSystemFlags,
targetContainer,
nextDiscreteEvent.nativeEvent,
);
if (nextBlockedOn !== null) {
if (nextBlockedOn === null) {
dispatchEventForPluginEventSystem(
nextDiscreteEvent.domEventName,
nextDiscreteEvent.eventSystemFlags,
nextDiscreteEvent.nativeEvent,
return_targetInst,
targetContainer,
);
} else {
// We're still blocked. Try again later.
nextDiscreteEvent.blockedOn = nextBlockedOn;
break;