Skip to content

Commit

Permalink
Decouple dispatching from attemptToDispatchEvent (#22851)
Browse files Browse the repository at this point in the history
* Decoupled dispatching from attemptToDispatchEvent

* Remove unnecessary field

It is unnecessary because it's only true when retval is null.
  • Loading branch information
gaearon authored Dec 2, 2021
1 parent ed00d2c commit ea5a413
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 19 deletions.
39 changes: 26 additions & 13 deletions packages/react-dom/src/events/ReactDOMEventListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -264,15 +278,20 @@ 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,
nativeEvent: AnyNativeEvent,
): null | Container | SuspenseInstance {
// TODO: Warn if _enabled is false.

return_targetInst = null;

const nativeEventTarget = getEventTarget(nativeEvent);
let targetInst = getClosestInstanceFromNode(nativeEventTarget);

Expand Down Expand Up @@ -313,13 +332,7 @@ export function attemptToDispatchEvent(
}
}
}
dispatchEventForPluginEventSystem(
domEventName,
eventSystemFlags,
nativeEvent,
targetInst,
targetContainer,
);
return_targetInst = targetInst;
// We're not blocked on anything.
return null;
}
Expand Down
32 changes: 26 additions & 6 deletions packages/react-dom/src/events/ReactDOMEventReplaying.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit ea5a413

Please sign in to comment.