Clean up Selective Hydration / Event Replay flag (#24156)
* clean up selective hydration / replay flag * dont export return_targetInst
salazarm committed
Mar 24, 2022 at 14:12 UTC
6b85823b35f75baec9022a40df336d6aee788ce0
19 files changed
+72
-565
packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+11
-80
@@ -2418,18 +2418,8 @@ describe('ReactDOMServerPartialHydration', () => {
2418
await promise;
2419
});
2420
2421
- if (
2422
- gate(
2423
- flags =>
2424
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
2425
- )
2426
- ) {
2427
- expect(clicks).toBe(0);
2428
- expect(container.textContent).toBe('Click meHello');
2429
- } else {
2430
- expect(clicks).toBe(1);
2431
- expect(container.textContent).toBe('Hello');
2432
- }
2421
+ expect(clicks).toBe(0);
2422
+ expect(container.textContent).toBe('Click meHello');
2423
document.body.removeChild(container);
2424
});
2425
@@ -2511,17 +2501,7 @@ describe('ReactDOMServerPartialHydration', () => {
2501
await promise;
2502
});
2503
2514
- if (
2515
- gate(
2516
- flags =>
2517
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
2518
- )
2519
- ) {
2520
- expect(onEvent).toHaveBeenCalledTimes(0);
2521
- } else {
2522
- expect(onEvent).toHaveBeenCalledTimes(2);
2523
- }
2524
-
2504
+ expect(onEvent).toHaveBeenCalledTimes(0);
2505
document.body.removeChild(container);
2506
});
2507
@@ -2601,16 +2581,7 @@ describe('ReactDOMServerPartialHydration', () => {
2581
await promise;
2582
});
2583
2604
- if (
2605
- gate(
2606
- flags =>
2607
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
2608
- )
2609
- ) {
2610
- expect(clicks).toBe(0);
2611
- } else {
2612
- expect(clicks).toBe(2);
2613
- }
2584
+ expect(clicks).toBe(0);
2585
2586
document.body.removeChild(container);
2587
});
@@ -2695,17 +2666,7 @@ describe('ReactDOMServerPartialHydration', () => {
2666
resolve();
2667
await promise;
2668
});
2698
- if (
2699
- gate(
2700
- flags =>
2701
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
2702
- )
2703
- ) {
2704
- expect(onEvent).toHaveBeenCalledTimes(0);
2705
- } else {
2706
- expect(onEvent).toHaveBeenCalledTimes(2);
2707
- }
2708
-
2669
+ expect(onEvent).toHaveBeenCalledTimes(0);
2670
document.body.removeChild(container);
2671
});
2672
@@ -2776,19 +2737,8 @@ describe('ReactDOMServerPartialHydration', () => {
2737
await promise;
2738
});
2739
2779
- if (
2780
- gate(
2781
- flags =>
2782
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
2783
- )
2784
- ) {
2785
- expect(clicksOnChild).toBe(0);
2786
- expect(clicksOnParent).toBe(0);
2787
- } else {
2788
- expect(clicksOnChild).toBe(1);
2789
- // This will be zero due to the stopPropagation.
2790
- expect(clicksOnParent).toBe(0);
2791
- }
2740
+ expect(clicksOnChild).toBe(0);
2741
+ expect(clicksOnParent).toBe(0);
2742
2743
document.body.removeChild(container);
2744
});
@@ -2864,16 +2814,7 @@ describe('ReactDOMServerPartialHydration', () => {
2814
});
2815
2816
// We're now full hydrated.
2867
- if (
2868
- gate(
2869
- flags =>
2870
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
2871
- )
2872
- ) {
2873
- expect(clicks).toBe(0);
2874
- } else {
2875
- expect(clicks).toBe(1);
2876
- }
2817
+ expect(clicks).toBe(0);
2818
2819
document.body.removeChild(parentContainer);
2820
});
@@ -3142,19 +3083,9 @@ describe('ReactDOMServerPartialHydration', () => {
3083
await promise;
3084
});
3085
3145
- if (
3146
- gate(
3147
- flags =>
3148
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
3149
- )
3150
- ) {
3151
- // discrete event not replayed
3152
- expect(submits).toBe(0);
3153
- expect(container.textContent).toBe('Click meHello');
3154
- } else {
3155
- expect(submits).toBe(1);
3156
- expect(container.textContent).toBe('Hello');
3157
- }
3086
+ // discrete event not replayed
3087
+ expect(submits).toBe(0);
3088
+ expect(container.textContent).toBe('Click meHello');
3089
3090
document.body.removeChild(container);
3091
});
packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js
+46
-176
@@ -268,18 +268,7 @@ describe('ReactDOMServerSelectiveHydration', () => {
268
await promise;
269
});
270
271
- if (
272
- gate(
273
- flags =>
274
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
275
- )
276
- ) {
277
- expect(Scheduler).toHaveYielded(['D', 'A']);
278
- } else {
279
- // After the click, we should prioritize D and the Click first,
280
- // and only after that render A and C.
281
- expect(Scheduler).toHaveYielded(['D', 'Clicked D', 'A']);
282
- }
271
+ expect(Scheduler).toHaveYielded(['D', 'A']);
272
273
document.body.removeChild(container);
274
});
@@ -353,16 +342,7 @@ describe('ReactDOMServerSelectiveHydration', () => {
342
dispatchClickEvent(spanC);
343
dispatchClickEvent(spanD);
344
356
- if (
357
- gate(
358
- flags =>
359
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
360
- )
361
- ) {
362
- expect(Scheduler).toHaveYielded(['App', 'C', 'Clicked C']);
363
- } else {
364
- expect(Scheduler).toHaveYielded(['App']);
365
- }
345
+ expect(Scheduler).toHaveYielded(['App', 'C', 'Clicked C']);
346
347
await act(async () => {
348
suspend = false;
@@ -370,29 +350,12 @@ describe('ReactDOMServerSelectiveHydration', () => {
350
await promise;
351
});
352
373
- if (
374
- ReactFeatureFlags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay
375
- ) {
376
- expect(Scheduler).toHaveYielded([
377
- 'A',
378
- 'D',
379
- // B should render last since it wasn't clicked.
380
- 'B',
381
- ]);
382
- } else {
383
- // We should prioritize hydrating A, C and D first since we clicked in
384
- // them. Only after they're done will we hydrate B.
385
- expect(Scheduler).toHaveYielded([
386
- 'A',
387
- 'Clicked A',
388
- 'C',
389
- 'Clicked C',
390
- 'D',
391
- 'Clicked D',
392
- // B should render last since it wasn't clicked.
393
- 'B',
394
- ]);
395
- }
353
+ expect(Scheduler).toHaveYielded([
354
+ 'A',
355
+ 'D',
356
+ // B should render last since it wasn't clicked.
357
+ 'B',
358
+ ]);
359
360
document.body.removeChild(container);
361
});
@@ -546,17 +509,8 @@ describe('ReactDOMServerSelectiveHydration', () => {
509
resolve();
510
await promise;
511
});
549
- if (
550
- gate(
551
- flags =>
552
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
553
- )
554
- ) {
555
- // no replay
556
- expect(Scheduler).toHaveYielded(['D', 'A']);
557
- } else {
558
- expect(Scheduler).toHaveYielded(['D', 'Clicked D', 'A']);
559
- }
512
+ // no replay
513
+ expect(Scheduler).toHaveYielded(['D', 'A']);
514
515
document.body.removeChild(container);
516
});
@@ -635,42 +589,19 @@ describe('ReactDOMServerSelectiveHydration', () => {
589
createEventTarget(spanC).virtualclick();
590
createEventTarget(spanD).virtualclick();
591
638
- if (
639
- ReactFeatureFlags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay
640
- ) {
641
- expect(Scheduler).toHaveYielded(['App', 'C', 'Clicked C']);
642
- } else {
643
- expect(Scheduler).toHaveYielded(['App']);
644
- }
592
+ expect(Scheduler).toHaveYielded(['App', 'C', 'Clicked C']);
593
await act(async () => {
594
suspend = false;
595
resolve();
596
await promise;
597
});
598
651
- if (
652
- ReactFeatureFlags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay
653
- ) {
654
- expect(Scheduler).toHaveYielded([
655
- 'A',
656
- 'D',
657
- // B should render last since it wasn't clicked.
658
- 'B',
659
- ]);
660
- } else {
661
- // We should prioritize hydrating A, C and D first since we clicked in
662
- // them. Only after they're done will we hydrate B.
663
- expect(Scheduler).toHaveYielded([
664
- 'A',
665
- 'Clicked A',
666
- 'C',
667
- 'Clicked C',
668
- 'D',
669
- 'Clicked D',
670
- // B should render last since it wasn't clicked.
671
- 'B',
672
- ]);
673
- }
599
+ expect(Scheduler).toHaveYielded([
600
+ 'A',
601
+ 'D',
602
+ // B should render last since it wasn't clicked.
603
+ 'B',
604
+ ]);
605
606
document.body.removeChild(container);
607
});
@@ -750,37 +681,15 @@ describe('ReactDOMServerSelectiveHydration', () => {
681
resolve();
682
await promise;
683
});
753
- if (
754
- gate(
755
- flags =>
756
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
757
- )
758
- ) {
759
- // We should prioritize hydrating D first because we clicked it.
760
- // but event isnt replayed
761
- expect(Scheduler).toHaveYielded([
762
- 'D',
763
- 'B', // Ideally this should be later.
764
- 'C',
765
- 'Hover C',
766
- 'A',
767
- ]);
768
- } else {
769
- // We should prioritize hydrating D first because we clicked it.
770
- // Next we should hydrate C since that's the current hover target.
771
- // To simplify implementation details we hydrate both B and C at
772
- // the same time since B was already scheduled.
773
- // This is ok because it will at least not continue for nested
774
- // boundary. See the next test below.
775
- expect(Scheduler).toHaveYielded([
776
- 'D',
777
- 'Clicked D',
778
- 'B', // Ideally this should be later.
779
- 'C',
780
- 'Hover C',
781
- 'A',
782
- ]);
783
- }
684
+ // We should prioritize hydrating D first because we clicked it.
685
+ // but event isnt replayed
686
+ expect(Scheduler).toHaveYielded([
687
+ 'D',
688
+ 'B', // Ideally this should be later.
689
+ 'C',
690
+ 'Hover C',
691
+ 'A',
692
+ ]);
693
694
document.body.removeChild(container);
695
});
@@ -904,47 +813,22 @@ describe('ReactDOMServerSelectiveHydration', () => {
813
await promise;
814
});
815
907
- if (
908
- gate(
909
- flags =>
910
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
911
- )
912
- ) {
913
- // We should prioritize hydrating D first because we clicked it.
914
- // but event isnt replayed
915
- expect(Scheduler).toHaveYielded([
916
- 'D',
917
- 'B', // Ideally this should be later.
918
- 'C',
919
- // Mouse out events aren't replayed
920
- // 'Mouse Out Capture B',
921
- // 'Mouse Out B',
922
- 'Mouse Over Capture Parent',
923
- 'Mouse Over Capture C',
924
- // Stop propagation stops these
925
- // 'Mouse Over Capture Inner C',
926
- // 'Mouse Over C',
927
- 'A',
928
- ]);
929
- } else {
930
- // We should prioritize hydrating D first because we clicked it.
931
- // Next we should hydrate C since that's the current hover target.
932
- // To simplify implementation details we hydrate both B and C at
933
- // the same time since B was already scheduled.
934
- // This is ok because it will at least not continue for nested
935
- // boundary. See the next test below.
936
- expect(Scheduler).toHaveYielded([
937
- 'D',
938
- 'Clicked D',
939
- 'B', // Ideally this should be later.
940
- 'C',
941
- // Capture phase isn't replayed
942
- // Mouseout isn't replayed
943
- 'Mouse Over C',
944
- 'Mouse Enter C',
945
- 'A',
946
- ]);
947
- }
816
+ // We should prioritize hydrating D first because we clicked it.
817
+ // but event isnt replayed
818
+ expect(Scheduler).toHaveYielded([
819
+ 'D',
820
+ 'B', // Ideally this should be later.
821
+ 'C',
822
+ // Mouse out events aren't replayed
823
+ // 'Mouse Out Capture B',
824
+ // 'Mouse Out B',
825
+ 'Mouse Over Capture Parent',
826
+ 'Mouse Over Capture C',
827
+ // Stop propagation stops these
828
+ // 'Mouse Over Capture Inner C',
829
+ // 'Mouse Over C',
830
+ 'A',
831
+ ]);
832
833
// This test shows existing quirk where stopPropagation on mouseout
834
// prevents mouseEnter from firing
@@ -1091,19 +975,10 @@ describe('ReactDOMServerSelectiveHydration', () => {
975
});
976
977
expect(OuterScheduler).toHaveYielded(['Suspend Outer']);
1094
- if (
1095
- gate(
1096
- flags =>
1097
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
1098
- )
1099
- ) {
1100
- // InnerApp doesn't see the event because OuterApp calls stopPropagation in
1101
- // capture phase since the event is blocked on suspended component
1102
- expect(InnerScheduler).toHaveYielded([]);
1103
- } else {
1104
- // no stopPropagation
1105
- expect(InnerScheduler).toHaveYielded(['Suspend Inner']);
1106
- }
978
+
979
+ // InnerApp doesn't see the event because OuterApp calls stopPropagation in
980
+ // capture phase since the event is blocked on suspended component
981
+ expect(InnerScheduler).toHaveYielded([]);
982
983
expect(Scheduler).toHaveYielded([]);
984
});
@@ -1111,7 +986,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
986
document.body.innerHTML = '';
987
});
988
1114
- // @gate enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay
989
it('Inner hydrates first then Outer', async () => {
990
dispatchMouseHoverEvent(innerDiv);
991
@@ -1168,7 +1042,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
1042
]);
1043
});
1044
1171
- // @gate enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay
1045
it('Outer hydrates first then Inner', async () => {
1046
dispatchMouseHoverEvent(innerDiv);
1047
@@ -1230,7 +1103,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
1103
});
1104
});
1105
1233
- // @gate enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay
1106
it('replays event with null target when tree is dismounted', async () => {
1107
let suspend = false;
1108
let resolve;
@@ -1549,7 +1421,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
1421
document.body.removeChild(container);
1422
});
1423
1552
- // @gate enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay
1424
it('fires capture event handlers and native events if content is hydratable during discrete event', async () => {
1425
spyOnDev(console, 'error');
1426
function Child({text}) {
@@ -1633,7 +1504,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
1504
document.body.removeChild(container);
1505
});
1506
1636
- // @gate enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay
1507
it('does not propagate discrete event if it cannot be synchronously hydrated', async () => {
1508
let triggeredParent = false;
1509
let triggeredChild = false;
packages/react-dom/src/client/ReactDOM.js
-3
@@ -37,7 +37,6 @@ import {
37
flushControlled,
38
injectIntoDevTools,
39
attemptSynchronousHydration,
40
- attemptDiscreteHydration,
40
attemptContinuousHydration,
41
attemptHydrationAtCurrentPriority,
42
} from 'react-reconciler/src/ReactFiberReconciler';
@@ -59,7 +58,6 @@ import {
58
import {restoreControlledState} from './ReactDOMComponent';
59
import {
60
setAttemptSynchronousHydration,
62
- setAttemptDiscreteHydration,
61
setAttemptContinuousHydration,
62
setAttemptHydrationAtCurrentPriority,
63
setGetCurrentUpdatePriority,
@@ -73,7 +71,6 @@ import {
71
} from '../events/ReactDOMControlledComponent';
72
73
setAttemptSynchronousHydration(attemptSynchronousHydration);
76
-setAttemptDiscreteHydration(attemptDiscreteHydration);
74
setAttemptContinuousHydration(attemptContinuousHydration);
75
setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority);
76
setGetCurrentUpdatePriority(getCurrentUpdatePriority);
packages/react-dom/src/events/ReactDOMEventListener.js
+2
-121
@@ -11,11 +11,8 @@ import type {AnyNativeEvent} from '../events/PluginModuleType';
11
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
12
import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
13
import type {DOMEventName} from '../events/DOMEventNames';
14
-import {enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay} from 'shared/ReactFeatureFlags';
14
import {
15
isDiscreteEventThatRequiresHydration,
17
- queueDiscreteEvent,
18
- hasQueuedDiscreteEvents,
16
clearIfContinuousEvent,
17
queueIfContinuousEvent,
18
attemptSynchronousHydration,
@@ -146,123 +143,7 @@ function dispatchContinuousEvent(
143
}
144
}
145
149
-export function dispatchEvent(
150
- domEventName: DOMEventName,
151
- eventSystemFlags: EventSystemFlags,
152
- targetContainer: EventTarget,
153
- nativeEvent: AnyNativeEvent,
154
-): void {
155
- if (!_enabled) {
156
- return;
157
- }
158
- if (enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay) {
159
- dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(
160
- domEventName,
161
- eventSystemFlags,
162
- targetContainer,
163
- nativeEvent,
164
- );
165
- } else {
166
- dispatchEventOriginal(
167
- domEventName,
168
- eventSystemFlags,
169
- targetContainer,
170
- nativeEvent,
171
- );
172
- }
173
-}
174
-
175
-function dispatchEventOriginal(
176
- domEventName: DOMEventName,
177
- eventSystemFlags: EventSystemFlags,
178
- targetContainer: EventTarget,
179
- nativeEvent: AnyNativeEvent,
180
-) {
181
- // TODO: replaying capture phase events is currently broken
182
- // because we used to do it during top-level native bubble handlers
183
- // but now we use different bubble and capture handlers.
184
- // In eager mode, we attach capture listeners early, so we need
185
- // to filter them out until we fix the logic to handle them correctly.
186
- const allowReplay = (eventSystemFlags & IS_CAPTURE_PHASE) === 0;
187
-
188
- if (
189
- allowReplay &&
190
- hasQueuedDiscreteEvents() &&
191
- isDiscreteEventThatRequiresHydration(domEventName)
192
- ) {
193
- // If we already have a queue of discrete events, and this is another discrete
194
- // event, then we can't dispatch it regardless of its target, since they
195
- // need to dispatch in order.
196
- queueDiscreteEvent(
197
- null, // Flags that we're not actually blocked on anything as far as we know.
198
- domEventName,
199
- eventSystemFlags,
200
- targetContainer,
201
- nativeEvent,
202
- );
203
- return;
204
- }
205
-
206
- const blockedOn = findInstanceBlockingEvent(
207
- domEventName,
208
- eventSystemFlags,
209
- targetContainer,
210
- nativeEvent,
211
- );
212
- if (blockedOn === null) {
213
- dispatchEventForPluginEventSystem(
214
- domEventName,
215
- eventSystemFlags,
216
- nativeEvent,
217
- return_targetInst,
218
- targetContainer,
219
- );
220
- if (allowReplay) {
221
- clearIfContinuousEvent(domEventName, nativeEvent);
222
- }
223
- return;
224
- }
225
-
226
- if (allowReplay) {
227
- if (isDiscreteEventThatRequiresHydration(domEventName)) {
228
- // This this to be replayed later once the target is available.
229
- queueDiscreteEvent(
230
- blockedOn,
231
- domEventName,
232
- eventSystemFlags,
233
- targetContainer,
234
- nativeEvent,
235
- );
236
- return;
237
- }
238
- if (
239
- queueIfContinuousEvent(
240
- blockedOn,
241
- domEventName,
242
- eventSystemFlags,
243
- targetContainer,
244
- nativeEvent,
245
- )
246
- ) {
247
- return;
248
- }
249
- // We need to clear only if we didn't queue because
250
- // queueing is accumulative.
251
- clearIfContinuousEvent(domEventName, nativeEvent);
252
- }
253
-
254
- // This is not replayable so we'll invoke it but without a target,
255
- // in case the event system needs to trace it.
256
- dispatchEventForPluginEventSystem(
257
- domEventName,
258
- eventSystemFlags,
259
- nativeEvent,
260
- null,
261
- targetContainer,
262
- );
263
-}
264
-
265
-function dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(
146
+function dispatchEvent(
147
domEventName: DOMEventName,
148
eventSystemFlags: EventSystemFlags,
149
targetContainer: EventTarget,
@@ -348,7 +229,7 @@ function dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEve
229
);
230
}
231
351
-export let return_targetInst = null;
232
+let return_targetInst = null;
233
234
// Returns a SuspenseInstance or Container if it's blocked.
235
// The return_targetInst field above is conceptually part of the return value.
packages/react-dom/src/events/ReactDOMEventReplaying.js
+12
-130
@@ -14,10 +14,7 @@ import type {EventSystemFlags} from './EventSystemFlags';
14
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
15
import type {EventPriority} from 'react-reconciler/src/ReactEventPriorities';
16
17
-import {
18
- enableSelectiveHydration,
19
- enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
20
-} from 'shared/ReactFeatureFlags';
17
+import {enableSelectiveHydration} from 'shared/ReactFeatureFlags';
18
import {
19
unstable_scheduleCallback as scheduleCallback,
20
unstable_NormalPriority as NormalPriority,
@@ -27,12 +24,8 @@ import {
24
getContainerFromFiber,
25
getSuspenseInstanceFromFiber,
26
} from 'react-reconciler/src/ReactFiberTreeReflection';
30
-import {
31
- findInstanceBlockingEvent,
32
- return_targetInst,
33
-} from './ReactDOMEventListener';
27
+import {findInstanceBlockingEvent} from './ReactDOMEventListener';
28
import {setReplayingEvent, resetReplayingEvent} from './CurrentReplayingEvent';
35
-import {dispatchEventForPluginEventSystem} from './DOMPluginEventSystem';
29
import {
30
getInstanceFromNode,
31
getClosestInstanceFromNode,
@@ -51,12 +44,6 @@ export function attemptSynchronousHydration(fiber: Object) {
44
_attemptSynchronousHydration(fiber);
45
}
46
54
-let attemptDiscreteHydration: (fiber: Object) => void;
55
-
56
-export function setAttemptDiscreteHydration(fn: (fiber: Object) => void) {
57
- attemptDiscreteHydration = fn;
58
-}
59
-
47
let attemptContinuousHydration: (fiber: Object) => void;
48
49
export function setAttemptContinuousHydration(fn: (fiber: Object) => void) {
@@ -133,7 +120,7 @@ export function hasQueuedContinuousEvents(): boolean {
120
return hasAnyQueuedContinuousEvents;
121
}
122
136
-const discreteReplayableEvents: Array<DOMEventName> = [
123
+const synchronouslyHydratedEvents: Array<DOMEventName> = [
124
'mousedown',
125
'mouseup',
126
'touchcancel',
@@ -167,7 +154,7 @@ const discreteReplayableEvents: Array<DOMEventName> = [
154
export function isDiscreteEventThatRequiresHydration(
155
eventType: DOMEventName,
156
): boolean {
170
- return discreteReplayableEvents.indexOf(eventType) > -1;
157
+ return synchronouslyHydratedEvents.indexOf(eventType) > -1;
158
}
159
160
function createQueuedReplayableEvent(
@@ -186,50 +173,6 @@ function createQueuedReplayableEvent(
173
};
174
}
175
189
-export function queueDiscreteEvent(
190
- blockedOn: null | Container | SuspenseInstance,
191
- domEventName: DOMEventName,
192
- eventSystemFlags: EventSystemFlags,
193
- targetContainer: EventTarget,
194
- nativeEvent: AnyNativeEvent,
195
-): void {
196
- if (enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay) {
197
- return;
198
- }
199
- const queuedEvent = createQueuedReplayableEvent(
200
- blockedOn,
201
- domEventName,
202
- eventSystemFlags,
203
- targetContainer,
204
- nativeEvent,
205
- );
206
- queuedDiscreteEvents.push(queuedEvent);
207
- if (enableSelectiveHydration) {
208
- if (queuedDiscreteEvents.length === 1) {
209
- // If this was the first discrete event, we might be able to
210
- // synchronously unblock it so that preventDefault still works.
211
- while (queuedEvent.blockedOn !== null) {
212
- const fiber = getInstanceFromNode(queuedEvent.blockedOn);
213
- if (fiber === null) {
214
- break;
215
- }
216
- attemptSynchronousHydration(fiber);
217
- if (queuedEvent.blockedOn === null) {
218
- // We got unblocked by hydration. Let's try again.
219
- replayUnblockedEvents();
220
- // If we're reblocked, on an inner boundary, we might need
221
- // to attempt hydrating that one.
222
- continue;
223
- } else {
224
- // We're still blocked from hydration, we have to give up
225
- // and replay later.
226
- break;
227
- }
228
- }
229
- }
230
- }
231
-}
232
-
176
// Resets the replaying for this type of continuous event to no event.
177
export function clearIfContinuousEvent(
178
domEventName: DOMEventName,
@@ -473,26 +416,14 @@ function attemptReplayContinuousQueuedEvent(
416
queuedEvent.nativeEvent,
417
);
418
if (nextBlockedOn === null) {
476
- if (enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay) {
477
- const nativeEvent = queuedEvent.nativeEvent;
478
- const nativeEventClone = new nativeEvent.constructor(
479
- nativeEvent.type,
480
- (nativeEvent: any),
481
- );
482
- setReplayingEvent(nativeEventClone);
483
- nativeEvent.target.dispatchEvent(nativeEventClone);
484
- resetReplayingEvent();
485
- } else {
486
- setReplayingEvent(queuedEvent.nativeEvent);
487
- dispatchEventForPluginEventSystem(
488
- queuedEvent.domEventName,
489
- queuedEvent.eventSystemFlags,
490
- queuedEvent.nativeEvent,
491
- return_targetInst,
492
- targetContainer,
493
- );
494
- resetReplayingEvent();
495
- }
419
+ const nativeEvent = queuedEvent.nativeEvent;
420
+ const nativeEventClone = new nativeEvent.constructor(
421
+ nativeEvent.type,
422
+ (nativeEvent: any),
423
+ );
424
+ setReplayingEvent(nativeEventClone);
425
+ nativeEvent.target.dispatchEvent(nativeEventClone);
426
+ resetReplayingEvent();
427
} else {
428
// We're still blocked. Try again later.
429
const fiber = getInstanceFromNode(nextBlockedOn);
@@ -520,55 +451,6 @@ function attemptReplayContinuousQueuedEventInMap(
451
452
function replayUnblockedEvents() {
453
hasScheduledReplayAttempt = false;
523
- if (!enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay) {
524
- // First replay discrete events.
525
- while (queuedDiscreteEvents.length > 0) {
526
- const nextDiscreteEvent = queuedDiscreteEvents[0];
527
- if (nextDiscreteEvent.blockedOn !== null) {
528
- // We're still blocked.
529
- // Increase the priority of this boundary to unblock
530
- // the next discrete event.
531
- const fiber = getInstanceFromNode(nextDiscreteEvent.blockedOn);
532
- if (fiber !== null) {
533
- attemptDiscreteHydration(fiber);
534
- }
535
- break;
536
- }
537
- const targetContainers = nextDiscreteEvent.targetContainers;
538
- while (targetContainers.length > 0) {
539
- const targetContainer = targetContainers[0];
540
- const nextBlockedOn = findInstanceBlockingEvent(
541
- nextDiscreteEvent.domEventName,
542
- nextDiscreteEvent.eventSystemFlags,
543
- targetContainer,
544
- nextDiscreteEvent.nativeEvent,
545
- );
546
- if (nextBlockedOn === null) {
547
- // This whole function is in !enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
548
- // so we don't need the new replay behavior code branch.
549
- setReplayingEvent(nextDiscreteEvent.nativeEvent);
550
- dispatchEventForPluginEventSystem(
551
- nextDiscreteEvent.domEventName,
552
- nextDiscreteEvent.eventSystemFlags,
553
- nextDiscreteEvent.nativeEvent,
554
- return_targetInst,
555
- targetContainer,
556
- );
557
- resetReplayingEvent();
558
- } else {
559
- // We're still blocked. Try again later.
560
- nextDiscreteEvent.blockedOn = nextBlockedOn;
561
- break;
562
- }
563
- // This target container was successfully dispatched. Try the next.
564
- targetContainers.shift();
565
- }
566
- if (nextDiscreteEvent.blockedOn === null) {
567
- // We've successfully replayed the first event. Let's try the next one.
568
- queuedDiscreteEvents.shift();
569
- }
570
- }
571
- }
454
// Next replay any continuous events.
455
if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
456
queuedFocus = null;
packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js
+1
-10
@@ -650,16 +650,7 @@ describe('DOMPluginEventSystem', () => {
650
651
// We're now full hydrated.
652
653
- if (
654
- gate(
655
- flags =>
656
- flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
657
- )
658
- ) {
659
- expect(clicks).toBe(0);
660
- } else {
661
- expect(clicks).toBe(1);
662
- }
653
+ expect(clicks).toBe(0);
654
655
document.body.removeChild(parentContainer);
656
});
packages/react-reconciler/src/ReactFiberReconciler.js
-5
@@ -27,7 +27,6 @@ import {
27
flushPassiveEffects as flushPassiveEffects_old,
28
getPublicRootInstance as getPublicRootInstance_old,
29
attemptSynchronousHydration as attemptSynchronousHydration_old,
30
- attemptDiscreteHydration as attemptDiscreteHydration_old,
30
attemptContinuousHydration as attemptContinuousHydration_old,
31
attemptHydrationAtCurrentPriority as attemptHydrationAtCurrentPriority_old,
32
findHostInstance as findHostInstance_old,
@@ -65,7 +64,6 @@ import {
64
flushPassiveEffects as flushPassiveEffects_new,
65
getPublicRootInstance as getPublicRootInstance_new,
66
attemptSynchronousHydration as attemptSynchronousHydration_new,
68
- attemptDiscreteHydration as attemptDiscreteHydration_new,
67
attemptContinuousHydration as attemptContinuousHydration_new,
68
attemptHydrationAtCurrentPriority as attemptHydrationAtCurrentPriority_new,
69
findHostInstance as findHostInstance_new,
@@ -124,9 +122,6 @@ export const getPublicRootInstance = enableNewReconciler
122
export const attemptSynchronousHydration = enableNewReconciler
123
? attemptSynchronousHydration_new
124
: attemptSynchronousHydration_old;
127
-export const attemptDiscreteHydration = enableNewReconciler
128
- ? attemptDiscreteHydration_new
129
- : attemptDiscreteHydration_old;
125
export const attemptContinuousHydration = enableNewReconciler
126
? attemptContinuousHydration_new
127
: attemptContinuousHydration_old;
packages/react-reconciler/src/ReactFiberReconciler.new.js
-14
@@ -452,20 +452,6 @@ function markRetryLaneIfNotHydrated(fiber: Fiber, retryLane: Lane) {
452
}
453
}
454
455
-export function attemptDiscreteHydration(fiber: Fiber): void {
456
- if (fiber.tag !== SuspenseComponent) {
457
- // We ignore HostRoots here because we can't increase
458
- // their priority and they should not suspend on I/O,
459
- // since you have to wrap anything that might suspend in
460
- // Suspense.
461
- return;
462
- }
463
- const eventTime = requestEventTime();
464
- const lane = SyncLane;
465
- scheduleUpdateOnFiber(fiber, lane, eventTime);
466
- markRetryLaneIfNotHydrated(fiber, lane);
467
-}
468
-
455
export function attemptContinuousHydration(fiber: Fiber): void {
456
if (fiber.tag !== SuspenseComponent) {
457
// We ignore HostRoots here because we can't increase
packages/react-reconciler/src/ReactFiberReconciler.old.js
-14
@@ -452,20 +452,6 @@ function markRetryLaneIfNotHydrated(fiber: Fiber, retryLane: Lane) {
452
}
453
}
454
455
-export function attemptDiscreteHydration(fiber: Fiber): void {
456
- if (fiber.tag !== SuspenseComponent) {
457
- // We ignore HostRoots here because we can't increase
458
- // their priority and they should not suspend on I/O,
459
- // since you have to wrap anything that might suspend in
460
- // Suspense.
461
- return;
462
- }
463
- const eventTime = requestEventTime();
464
- const lane = SyncLane;
465
- scheduleUpdateOnFiber(fiber, lane, eventTime);
466
- markRetryLaneIfNotHydrated(fiber, lane);
467
-}
468
-
455
export function attemptContinuousHydration(fiber: Fiber): void {
456
if (fiber.tag !== SuspenseComponent) {
457
// We ignore HostRoots here because we can't increase
packages/shared/ReactFeatureFlags.js
-3
@@ -44,9 +44,6 @@ export const enableSuspenseLayoutEffectSemantics = true;
44
export const enableClientRenderFallbackOnHydrationMismatch = true;
45
export const enableClientRenderFallbackOnTextMismatch = true;
46
47
-// TODO: Need to review this code one more time before landing
48
-export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
49
-
47
// Recoil still uses useMutableSource in www, need to delete
48
export const enableUseMutableSource = false;
49
packages/shared/forks/ReactFeatureFlags.native-fb.js
-1
@@ -52,7 +52,6 @@ export const warnAboutSpreadingKeyToJSX = false;
52
export const enableSuspenseAvoidThisFallback = false;
53
export const enableSuspenseAvoidThisFallbackFizz = false;
54
export const enableCPUSuspense = true;
55
-export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
55
export const enableClientRenderFallbackOnHydrationMismatch = true;
56
export const enableClientRenderFallbackOnTextMismatch = true;
57
export const enableComponentStackLocations = false;
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -43,7 +43,6 @@ export const warnAboutSpreadingKeyToJSX = false;
43
export const enableSuspenseAvoidThisFallback = false;
44
export const enableSuspenseAvoidThisFallbackFizz = false;
45
export const enableCPUSuspense = false;
46
-export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
46
export const enableClientRenderFallbackOnHydrationMismatch = true;
47
export const enableClientRenderFallbackOnTextMismatch = true;
48
export const enableComponentStackLocations = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -43,7 +43,6 @@ export const warnAboutSpreadingKeyToJSX = false;
43
export const enableSuspenseAvoidThisFallback = false;
44
export const enableSuspenseAvoidThisFallbackFizz = false;
45
export const enableCPUSuspense = false;
46
-export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
46
export const enableClientRenderFallbackOnHydrationMismatch = true;
47
export const enableClientRenderFallbackOnTextMismatch = true;
48
export const enableComponentStackLocations = true;
packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
-1
@@ -53,7 +53,6 @@ export const deferRenderPhaseUpdateToNextBatch = false;
53
export const enableSuspenseAvoidThisFallback = false;
54
export const enableSuspenseAvoidThisFallbackFizz = false;
55
export const enableCPUSuspense = false;
56
-export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
56
export const enableClientRenderFallbackOnHydrationMismatch = true;
57
export const enableClientRenderFallbackOnTextMismatch = true;
58
export const enableStrictEffects = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-1
@@ -43,7 +43,6 @@ export const warnAboutSpreadingKeyToJSX = false;
43
export const enableSuspenseAvoidThisFallback = true;
44
export const enableSuspenseAvoidThisFallbackFizz = false;
45
export const enableCPUSuspense = false;
46
-export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
46
export const enableClientRenderFallbackOnHydrationMismatch = true;
47
export const enableClientRenderFallbackOnTextMismatch = true;
48
export const enableComponentStackLocations = true;
packages/shared/forks/ReactFeatureFlags.testing.js
-1
@@ -43,7 +43,6 @@ export const warnAboutSpreadingKeyToJSX = false;
43
export const enableSuspenseAvoidThisFallback = false;
44
export const enableSuspenseAvoidThisFallbackFizz = false;
45
export const enableCPUSuspense = false;
46
-export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
46
export const enableClientRenderFallbackOnHydrationMismatch = true;
47
export const enableClientRenderFallbackOnTextMismatch = true;
48
export const enableComponentStackLocations = true;
packages/shared/forks/ReactFeatureFlags.testing.www.js
-1
@@ -43,7 +43,6 @@ export const warnAboutSpreadingKeyToJSX = false;
43
export const enableSuspenseAvoidThisFallback = true;
44
export const enableSuspenseAvoidThisFallbackFizz = false;
45
export const enableCPUSuspense = true;
46
-export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
46
export const enableClientRenderFallbackOnHydrationMismatch = true;
47
export const enableClientRenderFallbackOnTextMismatch = true;
48
export const enableComponentStackLocations = true;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
-1
@@ -25,7 +25,6 @@ export const disableSchedulerTimeoutInWorkLoop = __VARIANT__;
25
export const enableLazyContextPropagation = __VARIANT__;
26
export const enableSyncDefaultUpdates = __VARIANT__;
27
export const consoleManagedByDevToolsDuringStrictMode = __VARIANT__;
28
-export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = __VARIANT__;
28
export const enableClientRenderFallbackOnHydrationMismatch = __VARIANT__;
29
export const enableClientRenderFallbackOnTextMismatch = __VARIANT__;
30
export const enableTransitionTracing = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.www.js
-1
@@ -31,7 +31,6 @@ export const {
31
disableSchedulerTimeoutInWorkLoop,
32
enableLazyContextPropagation,
33
enableSyncDefaultUpdates,
34
- enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
34
enableClientRenderFallbackOnHydrationMismatch,
35
enableClientRenderFallbackOnTextMismatch,
36
} = dynamicFeatureFlags;