Revert "Land enableClientRenderFallbackOnTextMismatch" (#24738)
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.
Andrew Clark committed
Jun 16, 2022 at 11:38 UTC
229c86af07302d40b70c41de18106f80fe89836c
15 files changed
+51
-8
packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+11
-5
@@ -3497,6 +3497,7 @@ describe('ReactDOMFizzServer', () => {
3497
);
3498
});
3499
3500
+ // @gate enableClientRenderFallbackOnTextMismatch
3501
it('#24384: Suspending should halt hydration warnings but still emit hydration warnings after unsuspending if mismatches are genuine', async () => {
3502
const makeApp = () => {
3503
let resolve, resolved;
@@ -3586,6 +3587,7 @@ describe('ReactDOMFizzServer', () => {
3587
expect(Scheduler).toFlushAndYield([]);
3588
});
3589
3590
+ // @gate enableClientRenderFallbackOnTextMismatch
3591
it('only warns once on hydration mismatch while within a suspense boundary', async () => {
3592
const originalConsoleError = console.error;
3593
const mockError = jest.fn();
@@ -4661,11 +4663,15 @@ describe('ReactDOMFizzServer', () => {
4663
},
4664
});
4665
expect(Scheduler).toFlushAndYield([]);
4664
- expect(errors).toEqual([
4665
- 'Text content does not match server-rendered HTML.',
4666
- 'Hydration failed because the initial UI does not match what was rendered on the server.',
4667
- 'There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.',
4668
- ]);
4666
+ expect(errors).toEqual(
4667
+ [
4668
+ gate(flags => flags.enableClientRenderFallbackOnTextMismatch)
4669
+ ? 'Text content does not match server-rendered HTML.'
4670
+ : null,
4671
+ 'Hydration failed because the initial UI does not match what was rendered on the server.',
4672
+ 'There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.',
4673
+ ].filter(Boolean),
4674
+ );
4675
expect(getVisibleChildren(container)).toEqual(
4676
<title>{['hello1', 'hello2']}</title>,
4677
);
packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js
+23
-2
@@ -86,7 +86,8 @@ describe('ReactDOMServerHydration', () => {
86
</div>
87
);
88
}
89
- expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
89
+ if (gate(flags => flags.enableClientRenderFallbackOnTextMismatch)) {
90
+ expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
91
Array [
92
"Warning: Text content did not match. Server: \\"server\\" Client: \\"client\\"
93
in main (at **)
@@ -97,6 +98,16 @@ describe('ReactDOMServerHydration', () => {
98
"Caught [There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.]",
99
]
100
`);
101
+ } else {
102
+ expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
103
+ Array [
104
+ "Warning: Text content did not match. Server: \\"server\\" Client: \\"client\\"
105
+ in main (at **)
106
+ in div (at **)
107
+ in Mismatch (at **)",
108
+ ]
109
+ `);
110
+ }
111
});
112
113
// @gate __DEV__
@@ -346,7 +357,8 @@ describe('ReactDOMServerHydration', () => {
357
function Mismatch({isClient}) {
358
return <div className="parent">{isClient && 'only'}</div>;
359
}
349
- expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
360
+ if (gate(flags => flags.enableClientRenderFallbackOnTextMismatch)) {
361
+ expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
362
Array [
363
"Warning: Text content did not match. Server: \\"\\" Client: \\"only\\"
364
in div (at **)
@@ -356,6 +368,15 @@ describe('ReactDOMServerHydration', () => {
368
"Caught [There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.]",
369
]
370
`);
371
+ } else {
372
+ expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
373
+ Array [
374
+ "Warning: Text content did not match. Server: \\"\\" Client: \\"only\\"
375
+ in div (at **)
376
+ in Mismatch (at **)",
377
+ ]
378
+ `);
379
+ }
380
});
381
382
// @gate __DEV__
packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+2
@@ -3416,6 +3416,7 @@ describe('ReactDOMServerPartialHydration', () => {
3416
);
3417
});
3418
3419
+ // @gate enableClientRenderFallbackOnTextMismatch
3420
it("falls back to client rendering when there's a text mismatch (direct text child)", async () => {
3421
function DirectTextChild({text}) {
3422
return <div>{text}</div>;
@@ -3447,6 +3448,7 @@ describe('ReactDOMServerPartialHydration', () => {
3448
]);
3449
});
3450
3451
+ // @gate enableClientRenderFallbackOnTextMismatch
3452
it("falls back to client rendering when there's a text mismatch (text child with siblings)", async () => {
3453
function Sibling() {
3454
return 'Sibling';
packages/react-dom/src/client/ReactDOMComponent.js
+2
-1
@@ -72,6 +72,7 @@ import {validateProperties as validateUnknownProperties} from '../shared/ReactDO
72
import {
73
enableTrustedTypesIntegration,
74
enableCustomElementPropertySupport,
75
+ enableClientRenderFallbackOnTextMismatch,
76
} from 'shared/ReactFeatureFlags';
77
import {
78
mediaEventTypes,
@@ -249,7 +250,7 @@ export function checkForUnmatchedText(
250
}
251
}
252
252
- if (isConcurrentMode) {
253
+ if (isConcurrentMode && enableClientRenderFallbackOnTextMismatch) {
254
// In concurrent roots, we throw when there's a text mismatch and revert to
255
// client rendering, up to the nearest Suspense boundary.
256
throw new Error('Text content does not match server-rendered HTML.');
packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js
+1
@@ -169,6 +169,7 @@ describe('useMutableSourceHydration', () => {
169
});
170
171
// @gate enableUseMutableSource
172
+ // @gate enableClientRenderFallbackOnTextMismatch
173
it('should detect a tear before hydrating a component', () => {
174
const source = createSource('one');
175
const mutableSource = createMutableSource(source, param => param.version);
packages/shared/ReactFeatureFlags.js
+3
@@ -31,6 +31,9 @@ export const enableSymbolFallbackForWWW = false;
31
// internal tests need to be updated. The open source behavior is correct.
32
export const skipUnmountedBoundaries = true;
33
34
+// TODO: Finish rolling out in www
35
+export const enableClientRenderFallbackOnTextMismatch = true;
36
+
37
// TODO: Need to review this code one more time before landing
38
export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
39
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -51,6 +51,7 @@ export const enableSuspenseAvoidThisFallback = false;
51
export const enableSuspenseAvoidThisFallbackFizz = false;
52
export const enableCPUSuspense = true;
53
export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
54
+export const enableClientRenderFallbackOnTextMismatch = true;
55
export const enableComponentStackLocations = false;
56
export const enableLegacyFBSupport = false;
57
export const enableFilterEmptyStringAttributesDOM = false;
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -41,6 +41,7 @@ export const enableSuspenseAvoidThisFallback = false;
41
export const enableSuspenseAvoidThisFallbackFizz = false;
42
export const enableCPUSuspense = false;
43
export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
44
+export const enableClientRenderFallbackOnTextMismatch = true;
45
export const enableComponentStackLocations = false;
46
export const enableLegacyFBSupport = false;
47
export const enableFilterEmptyStringAttributesDOM = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -41,6 +41,7 @@ export const enableSuspenseAvoidThisFallback = false;
41
export const enableSuspenseAvoidThisFallbackFizz = false;
42
export const enableCPUSuspense = false;
43
export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
44
+export const enableClientRenderFallbackOnTextMismatch = true;
45
export const enableComponentStackLocations = true;
46
export const enableLegacyFBSupport = false;
47
export const enableFilterEmptyStringAttributesDOM = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
+1
@@ -50,6 +50,7 @@ export const enableSuspenseAvoidThisFallback = false;
50
export const enableSuspenseAvoidThisFallbackFizz = false;
51
export const enableCPUSuspense = false;
52
export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
53
+export const enableClientRenderFallbackOnTextMismatch = true;
54
export const enableStrictEffects = false;
55
export const createRootStrictEffectsByDefault = false;
56
export const enableUseRefAccessWarning = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -41,6 +41,7 @@ export const enableSuspenseAvoidThisFallback = true;
41
export const enableSuspenseAvoidThisFallbackFizz = false;
42
export const enableCPUSuspense = false;
43
export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
44
+export const enableClientRenderFallbackOnTextMismatch = true;
45
export const enableComponentStackLocations = true;
46
export const enableLegacyFBSupport = false;
47
export const enableFilterEmptyStringAttributesDOM = false;
packages/shared/forks/ReactFeatureFlags.testing.js
+1
@@ -41,6 +41,7 @@ export const enableSuspenseAvoidThisFallback = false;
41
export const enableSuspenseAvoidThisFallbackFizz = false;
42
export const enableCPUSuspense = false;
43
export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
44
+export const enableClientRenderFallbackOnTextMismatch = true;
45
export const enableComponentStackLocations = true;
46
export const enableLegacyFBSupport = false;
47
export const enableFilterEmptyStringAttributesDOM = false;
packages/shared/forks/ReactFeatureFlags.testing.www.js
+1
@@ -41,6 +41,7 @@ export const enableSuspenseAvoidThisFallback = true;
41
export const enableSuspenseAvoidThisFallbackFizz = false;
42
export const enableCPUSuspense = true;
43
export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true;
44
+export const enableClientRenderFallbackOnTextMismatch = true;
45
export const enableComponentStackLocations = true;
46
export const enableLegacyFBSupport = !__EXPERIMENTAL__;
47
export const enableFilterEmptyStringAttributesDOM = false;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+1
@@ -26,6 +26,7 @@ export const enableLazyContextPropagation = __VARIANT__;
26
export const enableSyncDefaultUpdates = __VARIANT__;
27
export const consoleManagedByDevToolsDuringStrictMode = __VARIANT__;
28
export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = __VARIANT__;
29
+export const enableClientRenderFallbackOnTextMismatch = __VARIANT__;
30
export const enableTransitionTracing = __VARIANT__;
31
export const enableSymbolFallbackForWWW = __VARIANT__;
32
// Enable this flag to help with concurrent mode debugging.
packages/shared/forks/ReactFeatureFlags.www.js
+1
@@ -32,6 +32,7 @@ export const {
32
enableLazyContextPropagation,
33
enableSyncDefaultUpdates,
34
enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
35
+ enableClientRenderFallbackOnTextMismatch,
36
} = dynamicFeatureFlags;
37
38
// On WWW, __EXPERIMENTAL__ is used for a new modern build.