Decouple dispatching from attemptToDispatchEvent (#22851)
* Decoupled dispatching from attemptToDispatchEvent * Remove unnecessary field It is unnecessary because it's only true when retval is null.
Dan Abramov committed
Dec 2, 2021 at 13:55 UTC
ea5a413602e6a3beec9ba929930ebb73eeee8da0
2 files changed
+52
-19
packages/react-dom/src/events/ReactDOMEventListener.js
+26
-13
@@ -180,15 +180,20 @@ export function dispatchEvent(
180
return;
181
}
182
183
- let blockedOn = attemptToDispatchEvent(
183
+ let blockedOn = findInstanceBlockingEvent(
184
domEventName,
185
eventSystemFlags,
186
targetContainer,
187
nativeEvent,
188
);
189
-
189
if (blockedOn === null) {
191
- // We successfully dispatched this event.
190
+ dispatchEventForPluginEventSystem(
191
+ domEventName,
192
+ eventSystemFlags,
193
+ nativeEvent,
194
+ return_targetInst,
195
+ targetContainer,
196
+ );
197
if (allowReplay) {
198
clearIfContinuousEvent(domEventName, nativeEvent);
199
}
@@ -236,12 +241,21 @@ export function dispatchEvent(
241
if (fiber !== null) {
242
attemptSynchronousHydration(fiber);
243
}
239
- const nextBlockedOn = attemptToDispatchEvent(
244
+ const nextBlockedOn = findInstanceBlockingEvent(
245
domEventName,
246
eventSystemFlags,
247
targetContainer,
248
nativeEvent,
249
);
250
+ if (nextBlockedOn === null) {
251
+ dispatchEventForPluginEventSystem(
252
+ domEventName,
253
+ eventSystemFlags,
254
+ nativeEvent,
255
+ return_targetInst,
256
+ targetContainer,
257
+ );
258
+ }
259
if (nextBlockedOn === blockedOn) {
260
break;
261
}
@@ -264,8 +278,11 @@ export function dispatchEvent(
278
);
279
}
280
267
-// Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked.
268
-export function attemptToDispatchEvent(
281
+export let return_targetInst = null;
282
+
283
+// Returns a SuspenseInstance or Container if it's blocked.
284
+// The return_targetInst field above is conceptually part of the return value.
285
+export function findInstanceBlockingEvent(
286
domEventName: DOMEventName,
287
eventSystemFlags: EventSystemFlags,
288
targetContainer: EventTarget,
@@ -273,6 +290,8 @@ export function attemptToDispatchEvent(
290
): null | Container | SuspenseInstance {
291
// TODO: Warn if _enabled is false.
292
293
+ return_targetInst = null;
294
+
295
const nativeEventTarget = getEventTarget(nativeEvent);
296
let targetInst = getClosestInstanceFromNode(nativeEventTarget);
297
@@ -313,13 +332,7 @@ export function attemptToDispatchEvent(
332
}
333
}
334
}
316
- dispatchEventForPluginEventSystem(
317
- domEventName,
318
- eventSystemFlags,
319
- nativeEvent,
320
- targetInst,
321
- targetContainer,
322
- );
335
+ return_targetInst = targetInst;
336
// We're not blocked on anything.
337
return null;
338
}
packages/react-dom/src/events/ReactDOMEventReplaying.js
+26
-6
@@ -27,7 +27,11 @@ import {
27
getContainerFromFiber,
28
getSuspenseInstanceFromFiber,
29
} from 'react-reconciler/src/ReactFiberTreeReflection';
30
-import {attemptToDispatchEvent} from './ReactDOMEventListener';
30
+import {
31
+ findInstanceBlockingEvent,
32
+ return_targetInst,
33
+} from './ReactDOMEventListener';
34
+import {dispatchEventForPluginEventSystem} from './DOMPluginEventSystem';
35
import {
36
getInstanceFromNode,
37
getClosestInstanceFromNode,
@@ -389,7 +393,7 @@ export function queueIfContinuousEvent(
393
function attemptExplicitHydrationTarget(
394
queuedTarget: QueuedHydrationTarget,
395
): void {
392
- // TODO: This function shares a lot of logic with attemptToDispatchEvent.
396
+ // TODO: This function shares a lot of logic with findInstanceBlockingEvent.
397
// Try to unify them. It's a bit tricky since it would require two return
398
// values.
399
const targetInst = getClosestInstanceFromNode(queuedTarget.target);
@@ -462,13 +466,21 @@ function attemptReplayContinuousQueuedEvent(
466
const targetContainers = queuedEvent.targetContainers;
467
while (targetContainers.length > 0) {
468
const targetContainer = targetContainers[0];
465
- const nextBlockedOn = attemptToDispatchEvent(
469
+ const nextBlockedOn = findInstanceBlockingEvent(
470
queuedEvent.domEventName,
471
queuedEvent.eventSystemFlags,
472
targetContainer,
473
queuedEvent.nativeEvent,
474
);
471
- if (nextBlockedOn !== null) {
475
+ if (nextBlockedOn === null) {
476
+ dispatchEventForPluginEventSystem(
477
+ queuedEvent.domEventName,
478
+ queuedEvent.eventSystemFlags,
479
+ queuedEvent.nativeEvent,
480
+ return_targetInst,
481
+ targetContainer,
482
+ );
483
+ } else {
484
// We're still blocked. Try again later.
485
const fiber = getInstanceFromNode(nextBlockedOn);
486
if (fiber !== null) {
@@ -512,13 +524,21 @@ function replayUnblockedEvents() {
524
const targetContainers = nextDiscreteEvent.targetContainers;
525
while (targetContainers.length > 0) {
526
const targetContainer = targetContainers[0];
515
- const nextBlockedOn = attemptToDispatchEvent(
527
+ const nextBlockedOn = findInstanceBlockingEvent(
528
nextDiscreteEvent.domEventName,
529
nextDiscreteEvent.eventSystemFlags,
530
targetContainer,
531
nextDiscreteEvent.nativeEvent,
532
);
521
- if (nextBlockedOn !== null) {
533
+ if (nextBlockedOn === null) {
534
+ dispatchEventForPluginEventSystem(
535
+ nextDiscreteEvent.domEventName,
536
+ nextDiscreteEvent.eventSystemFlags,
537
+ nextDiscreteEvent.nativeEvent,
538
+ return_targetInst,
539
+ targetContainer,
540
+ );
541
+ } else {
542
// We're still blocked. Try again later.
543
nextDiscreteEvent.blockedOn = nextBlockedOn;
544
break;