From 9693bb2e0d90ef06f5fa8f65ff2643958d0c7f81 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Fri, 31 Mar 2023 10:25:58 -0400 Subject: [PATCH] Clean up enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay (#26521) This flag is already enabled everywhere except for www, which is blocked by a few tests that assert on the old behavior. Once www is ready, I'll land this. --- .../src/events/ReactDOMEventListener.js | 116 +-------- .../src/events/ReactDOMEventReplaying.js | 130 +--------- ...DOMServerPartialHydration-test.internal.js | 92 +------ ...MServerSelectiveHydration-test.internal.js | 235 ++++-------------- .../DOMPluginEventSystem-test.internal.js | 13 +- .../src/ReactFiberReconciler.js | 17 -- packages/shared/ReactFeatureFlags.js | 4 - .../forks/ReactFeatureFlags.native-fb.js | 2 - .../forks/ReactFeatureFlags.native-oss.js | 2 - .../forks/ReactFeatureFlags.test-renderer.js | 2 - .../ReactFeatureFlags.test-renderer.native.js | 2 - .../ReactFeatureFlags.test-renderer.www.js | 2 - .../forks/ReactFeatureFlags.www-dynamic.js | 2 - .../shared/forks/ReactFeatureFlags.www.js | 1 - 14 files changed, 74 insertions(+), 546 deletions(-) diff --git a/packages/react-dom-bindings/src/events/ReactDOMEventListener.js b/packages/react-dom-bindings/src/events/ReactDOMEventListener.js index d5dcb5593d1d4..ae1e981d8c1d1 100644 --- a/packages/react-dom-bindings/src/events/ReactDOMEventListener.js +++ b/packages/react-dom-bindings/src/events/ReactDOMEventListener.js @@ -12,11 +12,9 @@ import type {AnyNativeEvent} from '../events/PluginModuleType'; import type {Fiber, FiberRoot} from 'react-reconciler/src/ReactInternalTypes'; import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig'; import type {DOMEventName} from '../events/DOMEventNames'; -import {enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay} from 'shared/ReactFeatureFlags'; + import { isDiscreteEventThatRequiresHydration, - queueDiscreteEvent, - hasQueuedDiscreteEvents, clearIfContinuousEvent, queueIfContinuousEvent, } from './ReactDOMEventReplaying'; @@ -156,119 +154,7 @@ export function dispatchEvent( if (!_enabled) { return; } - if (enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay) { - dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay( - domEventName, - eventSystemFlags, - targetContainer, - nativeEvent, - ); - } else { - dispatchEventOriginal( - domEventName, - eventSystemFlags, - targetContainer, - nativeEvent, - ); - } -} - -function dispatchEventOriginal( - domEventName: DOMEventName, - eventSystemFlags: EventSystemFlags, - targetContainer: EventTarget, - nativeEvent: AnyNativeEvent, -) { - // TODO: replaying capture phase events is currently broken - // because we used to do it during top-level native bubble handlers - // but now we use different bubble and capture handlers. - // In eager mode, we attach capture listeners early, so we need - // to filter them out until we fix the logic to handle them correctly. - const allowReplay = (eventSystemFlags & IS_CAPTURE_PHASE) === 0; - if ( - allowReplay && - hasQueuedDiscreteEvents() && - isDiscreteEventThatRequiresHydration(domEventName) - ) { - // If we already have a queue of discrete events, and this is another discrete - // event, then we can't dispatch it regardless of its target, since they - // need to dispatch in order. - queueDiscreteEvent( - null, // Flags that we're not actually blocked on anything as far as we know. - domEventName, - eventSystemFlags, - targetContainer, - nativeEvent, - ); - return; - } - - const blockedOn = findInstanceBlockingEvent( - domEventName, - eventSystemFlags, - targetContainer, - nativeEvent, - ); - if (blockedOn === null) { - dispatchEventForPluginEventSystem( - domEventName, - eventSystemFlags, - nativeEvent, - return_targetInst, - targetContainer, - ); - if (allowReplay) { - clearIfContinuousEvent(domEventName, nativeEvent); - } - return; - } - - if (allowReplay) { - if (isDiscreteEventThatRequiresHydration(domEventName)) { - // This to be replayed later once the target is available. - queueDiscreteEvent( - blockedOn, - domEventName, - eventSystemFlags, - targetContainer, - nativeEvent, - ); - return; - } - if ( - queueIfContinuousEvent( - blockedOn, - domEventName, - eventSystemFlags, - targetContainer, - nativeEvent, - ) - ) { - return; - } - // We need to clear only if we didn't queue because - // queueing is accumulative. - clearIfContinuousEvent(domEventName, nativeEvent); - } - - // This is not replayable so we'll invoke it but without a target, - // in case the event system needs to trace it. - dispatchEventForPluginEventSystem( - domEventName, - eventSystemFlags, - nativeEvent, - null, - targetContainer, - ); -} - -function dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay( - domEventName: DOMEventName, - eventSystemFlags: EventSystemFlags, - targetContainer: EventTarget, - nativeEvent: AnyNativeEvent, -) { let blockedOn = findInstanceBlockingEvent( domEventName, eventSystemFlags, diff --git a/packages/react-dom-bindings/src/events/ReactDOMEventReplaying.js b/packages/react-dom-bindings/src/events/ReactDOMEventReplaying.js index 56cf0ba5f45e1..660bb0a942749 100644 --- a/packages/react-dom-bindings/src/events/ReactDOMEventReplaying.js +++ b/packages/react-dom-bindings/src/events/ReactDOMEventReplaying.js @@ -14,7 +14,6 @@ import type {EventSystemFlags} from './EventSystemFlags'; import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes'; import type {EventPriority} from 'react-reconciler/src/ReactEventPriorities'; -import {enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay} from 'shared/ReactFeatureFlags'; import { unstable_scheduleCallback as scheduleCallback, unstable_NormalPriority as NormalPriority, @@ -24,12 +23,8 @@ import { getContainerFromFiber, getSuspenseInstanceFromFiber, } from 'react-reconciler/src/ReactFiberTreeReflection'; -import { - findInstanceBlockingEvent, - return_targetInst, -} from './ReactDOMEventListener'; +import {findInstanceBlockingEvent} from './ReactDOMEventListener'; import {setReplayingEvent, resetReplayingEvent} from './CurrentReplayingEvent'; -import {dispatchEventForPluginEventSystem} from './DOMPluginEventSystem'; import { getInstanceFromNode, getClosestInstanceFromNode, @@ -39,8 +34,6 @@ import {isHigherEventPriority} from 'react-reconciler/src/ReactEventPriorities'; import {isRootDehydrated} from 'react-reconciler/src/ReactFiberShellHydration'; import { - attemptSynchronousHydration, - attemptDiscreteHydration, attemptContinuousHydration, attemptHydrationAtCurrentPriority, } from 'react-reconciler/src/ReactFiberReconciler'; @@ -150,48 +143,6 @@ function createQueuedReplayableEvent( }; } -export function queueDiscreteEvent( - blockedOn: null | Container | SuspenseInstance, - domEventName: DOMEventName, - eventSystemFlags: EventSystemFlags, - targetContainer: EventTarget, - nativeEvent: AnyNativeEvent, -): void { - if (enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay) { - return; - } - const queuedEvent = createQueuedReplayableEvent( - blockedOn, - domEventName, - eventSystemFlags, - targetContainer, - nativeEvent, - ); - queuedDiscreteEvents.push(queuedEvent); - if (queuedDiscreteEvents.length === 1) { - // If this was the first discrete event, we might be able to - // synchronously unblock it so that preventDefault still works. - while (queuedEvent.blockedOn !== null) { - const fiber = getInstanceFromNode(queuedEvent.blockedOn); - if (fiber === null) { - break; - } - attemptSynchronousHydration(fiber); - if (queuedEvent.blockedOn === null) { - // We got unblocked by hydration. Let's try again. - replayUnblockedEvents(); - // If we're reblocked, on an inner boundary, we might need - // to attempt hydrating that one. - continue; - } else { - // We're still blocked from hydration, we have to give up - // and replay later. - break; - } - } - } -} - // Resets the replaying for this type of continuous event to no event. export function clearIfContinuousEvent( domEventName: DOMEventName, @@ -433,26 +384,14 @@ function attemptReplayContinuousQueuedEvent( queuedEvent.nativeEvent, ); if (nextBlockedOn === null) { - if (enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay) { - const nativeEvent = queuedEvent.nativeEvent; - const nativeEventClone = new nativeEvent.constructor( - nativeEvent.type, - (nativeEvent: any), - ); - setReplayingEvent(nativeEventClone); - nativeEvent.target.dispatchEvent(nativeEventClone); - resetReplayingEvent(); - } else { - setReplayingEvent(queuedEvent.nativeEvent); - dispatchEventForPluginEventSystem( - queuedEvent.domEventName, - queuedEvent.eventSystemFlags, - queuedEvent.nativeEvent, - return_targetInst, - targetContainer, - ); - resetReplayingEvent(); - } + const nativeEvent = queuedEvent.nativeEvent; + const nativeEventClone = new nativeEvent.constructor( + nativeEvent.type, + (nativeEvent: any), + ); + setReplayingEvent(nativeEventClone); + nativeEvent.target.dispatchEvent(nativeEventClone); + resetReplayingEvent(); } else { // We're still blocked. Try again later. const fiber = getInstanceFromNode(nextBlockedOn); @@ -480,56 +419,7 @@ function attemptReplayContinuousQueuedEventInMap( function replayUnblockedEvents() { hasScheduledReplayAttempt = false; - if (!enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay) { - // First replay discrete events. - while (queuedDiscreteEvents.length > 0) { - const nextDiscreteEvent = queuedDiscreteEvents[0]; - if (nextDiscreteEvent.blockedOn !== null) { - // We're still blocked. - // Increase the priority of this boundary to unblock - // the next discrete event. - const fiber = getInstanceFromNode(nextDiscreteEvent.blockedOn); - if (fiber !== null) { - attemptDiscreteHydration(fiber); - } - break; - } - const targetContainers = nextDiscreteEvent.targetContainers; - while (targetContainers.length > 0) { - const targetContainer = targetContainers[0]; - const nextBlockedOn = findInstanceBlockingEvent( - nextDiscreteEvent.domEventName, - nextDiscreteEvent.eventSystemFlags, - targetContainer, - nextDiscreteEvent.nativeEvent, - ); - if (nextBlockedOn === null) { - // This whole function is in !enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - // so we don't need the new replay behavior code branch. - setReplayingEvent(nextDiscreteEvent.nativeEvent); - dispatchEventForPluginEventSystem( - nextDiscreteEvent.domEventName, - nextDiscreteEvent.eventSystemFlags, - nextDiscreteEvent.nativeEvent, - return_targetInst, - targetContainer, - ); - resetReplayingEvent(); - } else { - // We're still blocked. Try again later. - nextDiscreteEvent.blockedOn = nextBlockedOn; - break; - } - // This target container was successfully dispatched. Try the next. - targetContainers.shift(); - } - if (nextDiscreteEvent.blockedOn === null) { - // We've successfully replayed the first event. Let's try the next one. - queuedDiscreteEvents.shift(); - } - } - } - // Next replay any continuous events. + // Replay any continuous events. if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) { queuedFocus = null; } diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js index 862abce2677e3..498432186e191 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js @@ -2392,18 +2392,9 @@ describe('ReactDOMServerPartialHydration', () => { await promise; }); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - expect(clicks).toBe(0); - expect(container.textContent).toBe('Click meHello'); - } else { - expect(clicks).toBe(1); - expect(container.textContent).toBe('Hello'); - } + expect(clicks).toBe(0); + expect(container.textContent).toBe('Click meHello'); + document.body.removeChild(container); }); @@ -2484,16 +2475,7 @@ describe('ReactDOMServerPartialHydration', () => { await promise; }); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - expect(onEvent).toHaveBeenCalledTimes(0); - } else { - expect(onEvent).toHaveBeenCalledTimes(2); - } + expect(onEvent).toHaveBeenCalledTimes(0); document.body.removeChild(container); }); @@ -2573,16 +2555,7 @@ describe('ReactDOMServerPartialHydration', () => { await promise; }); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - expect(clicks).toBe(0); - } else { - expect(clicks).toBe(2); - } + expect(clicks).toBe(0); document.body.removeChild(container); }); @@ -2666,16 +2639,8 @@ describe('ReactDOMServerPartialHydration', () => { resolve(); await promise; }); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - expect(onEvent).toHaveBeenCalledTimes(0); - } else { - expect(onEvent).toHaveBeenCalledTimes(2); - } + + expect(onEvent).toHaveBeenCalledTimes(0); document.body.removeChild(container); }); @@ -2746,19 +2711,8 @@ describe('ReactDOMServerPartialHydration', () => { await promise; }); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - expect(clicksOnChild).toBe(0); - expect(clicksOnParent).toBe(0); - } else { - expect(clicksOnChild).toBe(1); - // This will be zero due to the stopPropagation. - expect(clicksOnParent).toBe(0); - } + expect(clicksOnChild).toBe(0); + expect(clicksOnParent).toBe(0); document.body.removeChild(container); }); @@ -2830,17 +2784,7 @@ describe('ReactDOMServerPartialHydration', () => { await promise; }); - // We're now full hydrated. - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - expect(clicks).toBe(0); - } else { - expect(clicks).toBe(1); - } + expect(clicks).toBe(0); document.body.removeChild(parentContainer); }); @@ -3105,19 +3049,9 @@ describe('ReactDOMServerPartialHydration', () => { await promise; }); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - // discrete event not replayed - expect(submits).toBe(0); - expect(container.textContent).toBe('Click meHello'); - } else { - expect(submits).toBe(1); - expect(container.textContent).toBe('Hello'); - } + // discrete event not replayed + expect(submits).toBe(0); + expect(container.textContent).toBe('Click meHello'); document.body.removeChild(container); }); diff --git a/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js index 6b51c9a189088..31d3bba687d38 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js @@ -293,18 +293,7 @@ describe('ReactDOMServerSelectiveHydration', () => { await promise; }); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - assertLog(['D', 'A']); - } else { - // After the click, we should prioritize D and the Click first, - // and only after that render A and C. - assertLog(['D', 'Clicked D', 'A']); - } + assertLog(['D', 'A']); document.body.removeChild(container); }); @@ -378,16 +367,7 @@ describe('ReactDOMServerSelectiveHydration', () => { dispatchClickEvent(spanC); dispatchClickEvent(spanD); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - assertLog(['App', 'C', 'Clicked C']); - } else { - assertLog(['App']); - } + assertLog(['App', 'C', 'Clicked C']); await act(async () => { suspend = false; @@ -395,29 +375,12 @@ describe('ReactDOMServerSelectiveHydration', () => { await promise; }); - if ( - ReactFeatureFlags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay - ) { - assertLog([ - 'A', - 'D', - // B should render last since it wasn't clicked. - 'B', - ]); - } else { - // We should prioritize hydrating A, C and D first since we clicked in - // them. Only after they're done will we hydrate B. - assertLog([ - 'A', - 'Clicked A', - 'C', - 'Clicked C', - 'D', - 'Clicked D', - // B should render last since it wasn't clicked. - 'B', - ]); - } + assertLog([ + 'A', + 'D', + // B should render last since it wasn't clicked. + 'B', + ]); document.body.removeChild(container); }); @@ -571,17 +534,9 @@ describe('ReactDOMServerSelectiveHydration', () => { resolve(); await promise; }); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - // no replay - assertLog(['D', 'A']); - } else { - assertLog(['D', 'Clicked D', 'A']); - } + + // no replay + assertLog(['D', 'A']); document.body.removeChild(container); }); @@ -660,42 +615,20 @@ describe('ReactDOMServerSelectiveHydration', () => { createEventTarget(spanC).virtualclick(); createEventTarget(spanD).virtualclick(); - if ( - ReactFeatureFlags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay - ) { - assertLog(['App', 'C', 'Clicked C']); - } else { - assertLog(['App']); - } + assertLog(['App', 'C', 'Clicked C']); + await act(async () => { suspend = false; resolve(); await promise; }); - if ( - ReactFeatureFlags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay - ) { - assertLog([ - 'A', - 'D', - // B should render last since it wasn't clicked. - 'B', - ]); - } else { - // We should prioritize hydrating A, C and D first since we clicked in - // them. Only after they're done will we hydrate B. - assertLog([ - 'A', - 'Clicked A', - 'C', - 'Clicked C', - 'D', - 'Clicked D', - // B should render last since it wasn't clicked. - 'B', - ]); - } + assertLog([ + 'A', + 'D', + // B should render last since it wasn't clicked. + 'B', + ]); document.body.removeChild(container); }); @@ -779,37 +712,15 @@ describe('ReactDOMServerSelectiveHydration', () => { resolve(); }); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - // We should prioritize hydrating D first because we clicked it. - // but event isnt replayed - assertLog([ - 'D', - 'B', // Ideally this should be later. - 'C', - 'Hover C', - 'A', - ]); - } else { - // We should prioritize hydrating D first because we clicked it. - // Next we should hydrate C since that's the current hover target. - // To simplify implementation details we hydrate both B and C at - // the same time since B was already scheduled. - // This is ok because it will at least not continue for nested - // boundary. See the next test below. - assertLog([ - 'D', - 'Clicked D', - 'B', // Ideally this should be later. - 'C', - 'Hover C', - 'A', - ]); - } + // We should prioritize hydrating D first because we clicked it. + // but event isnt replayed + assertLog([ + 'D', + 'B', // Ideally this should be later. + 'C', + 'Hover C', + 'A', + ]); document.body.removeChild(container); }); @@ -932,47 +843,22 @@ describe('ReactDOMServerSelectiveHydration', () => { resolve(); }); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - // We should prioritize hydrating D first because we clicked it. - // but event isnt replayed - assertLog([ - 'D', - 'B', // Ideally this should be later. - 'C', - // Mouse out events aren't replayed - // 'Mouse Out Capture B', - // 'Mouse Out B', - 'Mouse Over Capture Parent', - 'Mouse Over Capture C', - // Stop propagation stops these - // 'Mouse Over Capture Inner C', - // 'Mouse Over C', - 'A', - ]); - } else { - // We should prioritize hydrating D first because we clicked it. - // Next we should hydrate C since that's the current hover target. - // To simplify implementation details we hydrate both B and C at - // the same time since B was already scheduled. - // This is ok because it will at least not continue for nested - // boundary. See the next test below. - assertLog([ - 'D', - 'Clicked D', - 'B', // Ideally this should be later. - 'C', - // Capture phase isn't replayed - // Mouseout isn't replayed - 'Mouse Over C', - 'Mouse Enter C', - 'A', - ]); - } + // We should prioritize hydrating D first because we clicked it. + // but event isnt replayed + assertLog([ + 'D', + 'B', // Ideally this should be later. + 'C', + // Mouse out events aren't replayed + // 'Mouse Out Capture B', + // 'Mouse Out B', + 'Mouse Over Capture Parent', + 'Mouse Over Capture C', + // Stop propagation stops these + // 'Mouse Over Capture Inner C', + // 'Mouse Over C', + 'A', + ]); // This test shows existing quirk where stopPropagation on mouseout // prevents mouseEnter from firing @@ -1129,19 +1015,10 @@ describe('ReactDOMServerSelectiveHydration', () => { }); OuterTestUtils.assertLog(['Suspend Outer']); - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - // InnerApp doesn't see the event because OuterApp calls stopPropagation in - // capture phase since the event is blocked on suspended component - InnerTestUtils.assertLog([]); - } else { - // no stopPropagation - InnerTestUtils.assertLog(['Suspend Inner']); - } + + // InnerApp doesn't see the event because OuterApp calls stopPropagation in + // capture phase since the event is blocked on suspended component + InnerTestUtils.assertLog([]); assertLog([]); }); @@ -1149,7 +1026,6 @@ describe('ReactDOMServerSelectiveHydration', () => { document.body.innerHTML = ''; }); - // @gate enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay it('Inner hydrates first then Outer', async () => { dispatchMouseHoverEvent(innerDiv); @@ -1191,7 +1067,6 @@ describe('ReactDOMServerSelectiveHydration', () => { assertLog(['Inner Mouse Enter', 'Outer Mouse Enter']); }); - // @gate enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay it('Outer hydrates first then Inner', async () => { dispatchMouseHoverEvent(innerDiv); @@ -1250,7 +1125,6 @@ describe('ReactDOMServerSelectiveHydration', () => { }); }); - // @gate enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay it('replays event with null target when tree is dismounted', async () => { let suspend = false; let resolve; @@ -1565,7 +1439,6 @@ describe('ReactDOMServerSelectiveHydration', () => { document.body.removeChild(container); }); - // @gate enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay it('fires capture event handlers and native events if content is hydratable during discrete event', async () => { spyOnDev(console, 'error'); function Child({text}) { @@ -1637,7 +1510,6 @@ describe('ReactDOMServerSelectiveHydration', () => { document.body.removeChild(container); }); - // @gate enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay it('does not propagate discrete event if it cannot be synchronously hydrated', async () => { let triggeredParent = false; let triggeredChild = false; @@ -1763,16 +1635,7 @@ describe('ReactDOMServerSelectiveHydration', () => { }); // The app should have successfully hydrated and rendered - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - assertLog(['App', 'A']); - } else { - assertLog(['App', 'A', 'Clicked A']); - } + assertLog(['App', 'A']); document.body.removeChild(container); }); diff --git a/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js b/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js index 0fefa4831413e..1a1769e82c07e 100644 --- a/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js +++ b/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js @@ -666,18 +666,7 @@ describe('DOMPluginEventSystem', () => { }); // We're now full hydrated. - - if ( - gate( - flags => - flags.enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, - ) - ) { - expect(clicks).toBe(0); - } else { - expect(clicks).toBe(1); - } - + expect(clicks).toBe(0); document.body.removeChild(parentContainer); }); diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index f7a1bf3102d5b..2b69b09edbff4 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -460,23 +460,6 @@ function markRetryLaneIfNotHydrated(fiber: Fiber, retryLane: Lane) { } } -export function attemptDiscreteHydration(fiber: Fiber): void { - if (fiber.tag !== SuspenseComponent) { - // We ignore HostRoots here because we can't increase - // their priority and they should not suspend on I/O, - // since you have to wrap anything that might suspend in - // Suspense. - return; - } - const lane = SyncLane; - const root = enqueueConcurrentRenderForLane(fiber, lane); - if (root !== null) { - const eventTime = requestEventTime(); - scheduleUpdateOnFiber(root, fiber, lane, eventTime); - } - markRetryLaneIfNotHydrated(fiber, lane); -} - export function attemptContinuousHydration(fiber: Fiber): void { if (fiber.tag !== SuspenseComponent) { // We ignore HostRoots here because we can't increase diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index dcd7eb6b27876..6d20fe0f9a9a2 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -37,10 +37,6 @@ export const revertRemovalOfSiblingPrerendering = false; // TODO: Finish rolling out in www export const enableClientRenderFallbackOnTextMismatch = true; -// TODO: Need to review this code one more time before landing -export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = - true; - // Recoil still uses useMutableSource in www, need to delete export const enableUseMutableSource = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 43946c62d6080..726a8aedb7916 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -52,8 +52,6 @@ export const enableCPUSuspense = true; export const enableUseHook = true; export const enableUseMemoCacheHook = true; export const enableUseEffectEventHook = false; -export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = - true; export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = false; export const enableLegacyFBSupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 3f9aa248a92d5..b069cb3bf7fb8 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -42,8 +42,6 @@ export const enableCPUSuspense = false; export const enableUseHook = true; export const enableUseMemoCacheHook = false; export const enableUseEffectEventHook = false; -export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = - true; export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = false; export const enableLegacyFBSupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index bf50fbbf7cbc9..d71e48ee9282d 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -42,8 +42,6 @@ export const enableCPUSuspense = false; export const enableUseHook = true; export const enableUseMemoCacheHook = false; export const enableUseEffectEventHook = false; -export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = - true; export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = true; export const enableLegacyFBSupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index 4c746f191e550..392a73ecd7b40 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -46,8 +46,6 @@ export const enableCPUSuspense = false; export const enableUseHook = true; export const enableUseMemoCacheHook = false; export const enableUseEffectEventHook = false; -export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = - true; export const enableClientRenderFallbackOnTextMismatch = true; export const createRootStrictEffectsByDefault = false; export const enableUseRefAccessWarning = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 439b7b9d9be89..54eb8bd7bc45c 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -42,8 +42,6 @@ export const enableCPUSuspense = false; export const enableUseHook = true; export const enableUseMemoCacheHook = false; export const enableUseEffectEventHook = false; -export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = - true; export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = true; export const enableLegacyFBSupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index 9682825117a4b..64670368b8401 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -21,8 +21,6 @@ export const enableProfilerNestedUpdateScheduledHook = __VARIANT__; export const disableSchedulerTimeoutInWorkLoop = __VARIANT__; export const enableLazyContextPropagation = __VARIANT__; export const enableUnifiedSyncLane = __VARIANT__; -export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = - __VARIANT__; export const enableTransitionTracing = __VARIANT__; export const enableCustomElementPropertySupport = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index b379a4001c49e..00f9ad5d00bc0 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -25,7 +25,6 @@ export const { enableUseRefAccessWarning, enableLazyContextPropagation, enableUnifiedSyncLane, - enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, enableTransitionTracing, enableCustomElementPropertySupport, } = dynamicFeatureFlags;