From 229c86af07302d40b70c41de18106f80fe89836c Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Thu, 16 Jun 2022 11:38:37 -0400 Subject: [PATCH] Revert "Land enableClientRenderFallbackOnTextMismatch" (#24738) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 327e4a1f96fbb874001b17684fbb073046a84938. Turns out we hadn't rolled this out internally yet — I mistook enableClientRenderFallbackOnHydrationMismatch for said enableClientRenderFallbackOnTextMismatch. Need to revert until we finish rolling out the change. --- .../src/__tests__/ReactDOMFizzServer-test.js | 16 ++++++++---- .../__tests__/ReactDOMHydrationDiff-test.js | 25 +++++++++++++++++-- ...DOMServerPartialHydration-test.internal.js | 2 ++ .../react-dom/src/client/ReactDOMComponent.js | 3 ++- .../useMutableSourceHydration-test.js | 1 + packages/shared/ReactFeatureFlags.js | 3 +++ .../forks/ReactFeatureFlags.native-fb.js | 1 + .../forks/ReactFeatureFlags.native-oss.js | 1 + .../forks/ReactFeatureFlags.test-renderer.js | 1 + .../ReactFeatureFlags.test-renderer.native.js | 1 + .../ReactFeatureFlags.test-renderer.www.js | 1 + .../shared/forks/ReactFeatureFlags.testing.js | 1 + .../forks/ReactFeatureFlags.testing.www.js | 1 + .../forks/ReactFeatureFlags.www-dynamic.js | 1 + .../shared/forks/ReactFeatureFlags.www.js | 1 + 15 files changed, 51 insertions(+), 8 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index 5d72131e483f7..5ff919693e232 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -3497,6 +3497,7 @@ describe('ReactDOMFizzServer', () => { ); }); + // @gate enableClientRenderFallbackOnTextMismatch it('#24384: Suspending should halt hydration warnings but still emit hydration warnings after unsuspending if mismatches are genuine', async () => { const makeApp = () => { let resolve, resolved; @@ -3586,6 +3587,7 @@ describe('ReactDOMFizzServer', () => { expect(Scheduler).toFlushAndYield([]); }); + // @gate enableClientRenderFallbackOnTextMismatch it('only warns once on hydration mismatch while within a suspense boundary', async () => { const originalConsoleError = console.error; const mockError = jest.fn(); @@ -4661,11 +4663,15 @@ describe('ReactDOMFizzServer', () => { }, }); expect(Scheduler).toFlushAndYield([]); - expect(errors).toEqual([ - 'Text content does not match server-rendered HTML.', - 'Hydration failed because the initial UI does not match what was rendered on the server.', - 'There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.', - ]); + expect(errors).toEqual( + [ + gate(flags => flags.enableClientRenderFallbackOnTextMismatch) + ? 'Text content does not match server-rendered HTML.' + : null, + 'Hydration failed because the initial UI does not match what was rendered on the server.', + 'There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.', + ].filter(Boolean), + ); expect(getVisibleChildren(container)).toEqual( {['hello1', 'hello2']}, ); diff --git a/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js b/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js index e1e9068eb101d..e8e7dffee5d6d 100644 --- a/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js @@ -86,7 +86,8 @@ describe('ReactDOMServerHydration', () => { ); } - expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` + if (gate(flags => flags.enableClientRenderFallbackOnTextMismatch)) { + expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` Array [ "Warning: Text content did not match. Server: \\"server\\" Client: \\"client\\" in main (at **) @@ -97,6 +98,16 @@ describe('ReactDOMServerHydration', () => { "Caught [There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.]", ] `); + } else { + expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` + Array [ + "Warning: Text content did not match. Server: \\"server\\" Client: \\"client\\" + in main (at **) + in div (at **) + in Mismatch (at **)", + ] + `); + } }); // @gate __DEV__ @@ -346,7 +357,8 @@ describe('ReactDOMServerHydration', () => { function Mismatch({isClient}) { return
{isClient && 'only'}
; } - expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` + if (gate(flags => flags.enableClientRenderFallbackOnTextMismatch)) { + expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` Array [ "Warning: Text content did not match. Server: \\"\\" Client: \\"only\\" in div (at **) @@ -356,6 +368,15 @@ describe('ReactDOMServerHydration', () => { "Caught [There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.]", ] `); + } else { + expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` + Array [ + "Warning: Text content did not match. Server: \\"\\" Client: \\"only\\" + in div (at **) + in Mismatch (at **)", + ] + `); + } }); // @gate __DEV__ diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js index bd9987dbfd8f2..e086448d6914d 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js @@ -3416,6 +3416,7 @@ describe('ReactDOMServerPartialHydration', () => { ); }); + // @gate enableClientRenderFallbackOnTextMismatch it("falls back to client rendering when there's a text mismatch (direct text child)", async () => { function DirectTextChild({text}) { return
{text}
; @@ -3447,6 +3448,7 @@ describe('ReactDOMServerPartialHydration', () => { ]); }); + // @gate enableClientRenderFallbackOnTextMismatch it("falls back to client rendering when there's a text mismatch (text child with siblings)", async () => { function Sibling() { return 'Sibling'; diff --git a/packages/react-dom/src/client/ReactDOMComponent.js b/packages/react-dom/src/client/ReactDOMComponent.js index 5a3ff307323df..19eb70e583b39 100644 --- a/packages/react-dom/src/client/ReactDOMComponent.js +++ b/packages/react-dom/src/client/ReactDOMComponent.js @@ -72,6 +72,7 @@ import {validateProperties as validateUnknownProperties} from '../shared/ReactDO import { enableTrustedTypesIntegration, enableCustomElementPropertySupport, + enableClientRenderFallbackOnTextMismatch, } from 'shared/ReactFeatureFlags'; import { mediaEventTypes, @@ -249,7 +250,7 @@ export function checkForUnmatchedText( } } - if (isConcurrentMode) { + if (isConcurrentMode && enableClientRenderFallbackOnTextMismatch) { // In concurrent roots, we throw when there's a text mismatch and revert to // client rendering, up to the nearest Suspense boundary. throw new Error('Text content does not match server-rendered HTML.'); diff --git a/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js b/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js index 183fecdc40bbe..a22e8114f605e 100644 --- a/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js +++ b/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js @@ -169,6 +169,7 @@ describe('useMutableSourceHydration', () => { }); // @gate enableUseMutableSource + // @gate enableClientRenderFallbackOnTextMismatch it('should detect a tear before hydrating a component', () => { const source = createSource('one'); const mutableSource = createMutableSource(source, param => param.version); diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 6b666217f41ba..33d233f92e4ef 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -31,6 +31,9 @@ export const enableSymbolFallbackForWWW = false; // internal tests need to be updated. The open source behavior is correct. export const skipUnmountedBoundaries = true; +// 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; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index f015f47c652ea..0e07c9f67d994 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -51,6 +51,7 @@ export const enableSuspenseAvoidThisFallback = false; export const enableSuspenseAvoidThisFallbackFizz = false; export const enableCPUSuspense = true; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true; +export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = false; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index c06c4f56c72d9..933d914ce5a62 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -41,6 +41,7 @@ export const enableSuspenseAvoidThisFallback = false; export const enableSuspenseAvoidThisFallbackFizz = false; export const enableCPUSuspense = false; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true; +export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = false; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 3770fd1943d28..b218c53470bda 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -41,6 +41,7 @@ export const enableSuspenseAvoidThisFallback = false; export const enableSuspenseAvoidThisFallbackFizz = false; export const enableCPUSuspense = false; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true; +export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = true; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index 557c50ba3e01b..b76a1b8506d13 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -50,6 +50,7 @@ export const enableSuspenseAvoidThisFallback = false; export const enableSuspenseAvoidThisFallbackFizz = false; export const enableCPUSuspense = false; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true; +export const enableClientRenderFallbackOnTextMismatch = true; export const enableStrictEffects = false; 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 3eb792406b9d9..63ba329f01a90 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -41,6 +41,7 @@ export const enableSuspenseAvoidThisFallback = true; export const enableSuspenseAvoidThisFallbackFizz = false; export const enableCPUSuspense = false; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true; +export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = true; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js index 32763075ce61f..9e5a9107ab2b1 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.js @@ -41,6 +41,7 @@ export const enableSuspenseAvoidThisFallback = false; export const enableSuspenseAvoidThisFallbackFizz = false; export const enableCPUSuspense = false; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true; +export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = true; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js index 59230d8e74461..a4c3e1ba32678 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.www.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -41,6 +41,7 @@ export const enableSuspenseAvoidThisFallback = true; export const enableSuspenseAvoidThisFallbackFizz = false; export const enableCPUSuspense = true; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true; +export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = true; export const enableLegacyFBSupport = !__EXPERIMENTAL__; export const enableFilterEmptyStringAttributesDOM = false; diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index 255a183d42ff1..7a89e41ad54f2 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -26,6 +26,7 @@ export const enableLazyContextPropagation = __VARIANT__; export const enableSyncDefaultUpdates = __VARIANT__; export const consoleManagedByDevToolsDuringStrictMode = __VARIANT__; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = __VARIANT__; +export const enableClientRenderFallbackOnTextMismatch = __VARIANT__; export const enableTransitionTracing = __VARIANT__; export const enableSymbolFallbackForWWW = __VARIANT__; // Enable this flag to help with concurrent mode debugging. diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 70f8ad6ff3d1b..938d7589c4e21 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -32,6 +32,7 @@ export const { enableLazyContextPropagation, enableSyncDefaultUpdates, enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, + enableClientRenderFallbackOnTextMismatch, } = dynamicFeatureFlags; // On WWW, __EXPERIMENTAL__ is used for a new modern build.