.",
- "Caught [Text content does not match server-rendered HTML.]",
- "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(`
- [
- "Warning: Text content did not match. Server: "" Client: "only"
- in div (at **)
- in Mismatch (at **)",
- ]
- `);
- }
+ expect(testMismatch(Mismatch)).toMatchInlineSnapshot(`
+ [
+ "Warning: Text content did not match. Server: "" Client: "only"
+ in div (at **)
+ in Mismatch (at **)",
+ "Warning: An error occurred during hydration. The server HTML was replaced with client content in
.",
+ "Caught [Text content does not match server-rendered HTML.]",
+ "Caught [There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.]",
+ ]
+ `);
});
// @gate __DEV__
diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationElements-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationElements-test.js
index d7dc81d2d4ef8..a66cd12cd9178 100644
--- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationElements-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationElements-test.js
@@ -18,7 +18,6 @@ let React;
let ReactDOM;
let ReactDOMClient;
let ReactDOMServer;
-let ReactFeatureFlags;
function initModules() {
jest.resetModules();
@@ -26,7 +25,6 @@ function initModules() {
ReactDOM = require('react-dom');
ReactDOMClient = require('react-dom/client');
ReactDOMServer = require('react-dom/server');
- ReactFeatureFlags = require('shared/ReactFeatureFlags');
// Make them available to the helpers.
return {
@@ -843,16 +841,15 @@ describe('ReactDOMServerIntegration', () => {
if (
render === serverRender ||
render === streamRender ||
- (render === clientRenderOnServerString &&
- ReactFeatureFlags.enableClientRenderFallbackOnTextMismatch)
+ render === clientRenderOnServerString
) {
expect(e.childNodes.length).toBe(1);
- // Everything becomes LF when parsed from server HTML or hydrated if enableClientRenderFallbackOnTextMismatch is on.
+ // Everything becomes LF when parsed from server HTML or hydrated.
// Null character is ignored.
expectNode(e.childNodes[0], TEXT_NODE_TYPE, 'foo\nbar\nbaz\nqux');
} else {
expect(e.childNodes.length).toBe(1);
- // Client rendering (or hydration without enableClientRenderFallbackOnTextMismatch) uses JS value with CR.
+ // Client rendering uses JS value with CR.
// Null character stays.
expectNode(
@@ -876,19 +873,18 @@ describe('ReactDOMServerIntegration', () => {
if (
render === serverRender ||
render === streamRender ||
- (render === clientRenderOnServerString &&
- ReactFeatureFlags.enableClientRenderFallbackOnTextMismatch)
+ render === clientRenderOnServerString
) {
// We have three nodes because there is a comment between them.
expect(e.childNodes.length).toBe(3);
- // Everything becomes LF when parsed from server HTML or hydrated if enableClientRenderFallbackOnTextMismatch is on.
+ // Everything becomes LF when parsed from server HTML or hydrated.
// Null character is ignored.
expectNode(e.childNodes[0], TEXT_NODE_TYPE, 'foo\nbar');
expectNode(e.childNodes[2], TEXT_NODE_TYPE, '\nbaz\nqux');
} else if (render === clientRenderOnServerString) {
// We have three nodes because there is a comment between them.
expect(e.childNodes.length).toBe(3);
- // Hydration without enableClientRenderFallbackOnTextMismatch uses JS value with CR and null character.
+ // Hydration uses JS value with CR and null character.
expectNode(e.childNodes[0], TEXT_NODE_TYPE, 'foo\rbar');
expectNode(e.childNodes[2], TEXT_NODE_TYPE, '\r\nbaz\nqux\u0000');
diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
index c8ce39f86e3bf..cbdbf7c3be805 100644
--- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
@@ -4059,7 +4059,6 @@ 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}
;
@@ -4091,7 +4090,6 @@ 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/__tests__/ReactRenderDocument-test.js b/packages/react-dom/src/__tests__/ReactRenderDocument-test.js
index f719be6981f10..a42c6848dcf93 100644
--- a/packages/react-dom/src/__tests__/ReactRenderDocument-test.js
+++ b/packages/react-dom/src/__tests__/ReactRenderDocument-test.js
@@ -265,9 +265,6 @@ describe('rendering React components at document', () => {
);
const testDocument = getTestDocument(markup);
- const enableClientRenderFallbackOnTextMismatch = gate(
- flags => flags.enableClientRenderFallbackOnTextMismatch,
- );
expect(() => {
ReactDOM.flushSync(() => {
ReactDOMClient.hydrateRoot(
@@ -281,25 +278,19 @@ describe('rendering React components at document', () => {
);
});
}).toErrorDev(
- enableClientRenderFallbackOnTextMismatch
- ? [
- 'Warning: An error occurred during hydration. The server HTML was replaced with client content in <#document>.',
- 'Warning: Text content did not match.',
- ]
- : ['Warning: Text content did not match.'],
+ [
+ 'Warning: An error occurred during hydration. The server HTML was replaced with client content in <#document>.',
+ 'Warning: Text content did not match.',
+ ],
{
- withoutStack: enableClientRenderFallbackOnTextMismatch ? 1 : 0,
+ withoutStack: 1,
},
);
- assertLog(
- enableClientRenderFallbackOnTextMismatch
- ? [
- 'Log recoverable error: Text content does not match server-rendered HTML.',
- 'Log recoverable error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.',
- ]
- : [],
- );
+ assertLog([
+ 'Log recoverable error: Text content does not match server-rendered HTML.',
+ 'Log recoverable error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.',
+ ]);
expect(testDocument.body.innerHTML).toBe('Hello world');
});
diff --git a/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js b/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
index e28296348afa7..76b6e4f947923 100644
--- a/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
+++ b/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
@@ -123,9 +123,6 @@ describe('ReactDOMServerHydration', () => {
// Now simulate a situation where the app is not idempotent. React should
// warn but do the right thing.
element.innerHTML = lastMarkup;
- const enableClientRenderFallbackOnTextMismatch = gate(
- flags => flags.enableClientRenderFallbackOnTextMismatch,
- );
await expect(async () => {
root = await act(() => {
return ReactDOMClient.hydrateRoot(
@@ -142,13 +139,11 @@ describe('ReactDOMServerHydration', () => {
);
});
}).toErrorDev(
- enableClientRenderFallbackOnTextMismatch
- ? [
- 'An error occurred during hydration. The server HTML was replaced with client content in
.',
- 'Text content did not match. Server: "x" Client: "y"',
- ]
- : ['Text content did not match. Server: "x" Client: "y"'],
- {withoutStack: enableClientRenderFallbackOnTextMismatch ? 1 : 0},
+ [
+ 'An error occurred during hydration. The server HTML was replaced with client content in
.',
+ 'Text content did not match. Server: "x" Client: "y"',
+ ],
+ {withoutStack: 1},
);
expect(mountCount).toEqual(4);
expect(element.innerHTML.length > 0).toBe(true);
@@ -218,9 +213,6 @@ describe('ReactDOMServerHydration', () => {
const onFocusAfterHydration = jest.fn();
element.firstChild.focus = onFocusBeforeHydration;
- const enableClientRenderFallbackOnTextMismatch = gate(
- flags => flags.enableClientRenderFallbackOnTextMismatch,
- );
await expect(async () => {
await act(() => {
ReactDOMClient.hydrateRoot(
@@ -232,15 +224,11 @@ describe('ReactDOMServerHydration', () => {
);
});
}).toErrorDev(
- enableClientRenderFallbackOnTextMismatch
- ? [
- 'An error occurred during hydration. The server HTML was replaced with client content in
.',
- 'Warning: Text content did not match. Server: "server" Client: "client"',
- ]
- : [
- 'Warning: Text content did not match. Server: "server" Client: "client"',
- ],
- {withoutStack: enableClientRenderFallbackOnTextMismatch ? 1 : 0},
+ [
+ 'An error occurred during hydration. The server HTML was replaced with client content in
.',
+ 'Warning: Text content did not match. Server: "server" Client: "client"',
+ ],
+ {withoutStack: 1},
);
expect(onFocusBeforeHydration).not.toHaveBeenCalled();
@@ -530,9 +518,6 @@ describe('ReactDOMServerHydration', () => {
);
domElement.innerHTML = markup;
- const enableClientRenderFallbackOnTextMismatch = gate(
- flags => flags.enableClientRenderFallbackOnTextMismatch,
- );
await expect(async () => {
await act(() => {
ReactDOMClient.hydrateRoot(
@@ -546,15 +531,11 @@ describe('ReactDOMServerHydration', () => {
expect(domElement.innerHTML).not.toEqual(markup);
}).toErrorDev(
- enableClientRenderFallbackOnTextMismatch
- ? [
- 'An error occurred during hydration. The server HTML was replaced with client content in
.',
- 'Warning: Text content did not match. Server: "server" Client: "client"',
- ]
- : [
- 'Warning: Text content did not match. Server: "server" Client: "client"',
- ],
- {withoutStack: enableClientRenderFallbackOnTextMismatch ? 1 : 0},
+ [
+ 'An error occurred during hydration. The server HTML was replaced with client content in
.',
+ 'Warning: Text content did not match. Server: "server" Client: "client"',
+ ],
+ {withoutStack: 1},
);
});
diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.js b/packages/react-reconciler/src/ReactFiberCompleteWork.js
index e8249b829379a..e7462bf24aa7e 100644
--- a/packages/react-reconciler/src/ReactFiberCompleteWork.js
+++ b/packages/react-reconciler/src/ReactFiberCompleteWork.js
@@ -1306,9 +1306,7 @@ function completeWork(
const currentHostContext = getHostContext();
const wasHydrated = popHydrationState(workInProgress);
if (wasHydrated) {
- if (prepareToHydrateHostTextInstance(workInProgress)) {
- markUpdate(workInProgress);
- }
+ prepareToHydrateHostTextInstance(workInProgress);
} else {
workInProgress.stateNode = createTextInstance(
newText,
diff --git a/packages/react-reconciler/src/ReactFiberHydrationContext.js b/packages/react-reconciler/src/ReactFiberHydrationContext.js
index 11cb591ec9a8b..dab48e40cd19b 100644
--- a/packages/react-reconciler/src/ReactFiberHydrationContext.js
+++ b/packages/react-reconciler/src/ReactFiberHydrationContext.js
@@ -27,7 +27,6 @@ import {
HostRoot,
SuspenseComponent,
} from './ReactWorkTags';
-import {enableClientRenderFallbackOnTextMismatch} from 'shared/ReactFeatureFlags';
import {createFiberFromDehydratedFragment} from './ReactFiber';
import {
@@ -489,7 +488,7 @@ function prepareToHydrateHostInstance(
);
}
-function prepareToHydrateHostTextInstance(fiber: Fiber): boolean {
+function prepareToHydrateHostTextInstance(fiber: Fiber): void {
if (!supportsHydration) {
throw new Error(
'Expected prepareToHydrateHostTextInstance() to never be called. ' +
@@ -500,13 +499,13 @@ function prepareToHydrateHostTextInstance(fiber: Fiber): boolean {
const textInstance: TextInstance = fiber.stateNode;
const textContent: string = fiber.memoizedProps;
const shouldWarnIfMismatchDev = !didSuspendOrErrorDEV;
- const shouldUpdate = hydrateTextInstance(
+ const textIsDifferent = hydrateTextInstance(
textInstance,
textContent,
fiber,
shouldWarnIfMismatchDev,
);
- if (shouldUpdate) {
+ if (textIsDifferent) {
// We assume that prepareToHydrateHostTextInstance is called in a context where the
// hydration parent is the parent host component of this host text.
const returnFiber = hydrationParentFiber;
@@ -520,11 +519,6 @@ function prepareToHydrateHostTextInstance(fiber: Fiber): boolean {
textContent,
shouldWarnIfMismatchDev,
);
- if (enableClientRenderFallbackOnTextMismatch) {
- // In concurrent mode we never update the mismatched text,
- // even if the error was ignored.
- return false;
- }
break;
}
case HostSingleton:
@@ -540,17 +534,11 @@ function prepareToHydrateHostTextInstance(fiber: Fiber): boolean {
textContent,
shouldWarnIfMismatchDev,
);
- if (enableClientRenderFallbackOnTextMismatch) {
- // In concurrent mode we never update the mismatched text,
- // even if the error was ignored.
- return false;
- }
break;
}
}
}
}
- return shouldUpdate;
}
function prepareToHydrateHostSuspenseInstance(fiber: Fiber): void {
diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js
index 8f7033421cd93..2b475046663e0 100644
--- a/packages/shared/ReactFeatureFlags.js
+++ b/packages/shared/ReactFeatureFlags.js
@@ -30,7 +30,6 @@ export const enableComponentStackLocations = true;
// -----------------------------------------------------------------------------
// TODO: Finish rolling out in www
-export const enableClientRenderFallbackOnTextMismatch = true;
export const enableAsyncActions = true;
// Need to remove didTimeout argument from Scheduler before landing
diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js
index 582cb140107e5..642af8be74d28 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js
@@ -65,7 +65,6 @@ export const enableSuspenseAvoidThisFallbackFizz = false;
export const enableCPUSuspense = true;
export const enableUseMemoCacheHook = true;
export const enableUseEffectEventHook = false;
-export const enableClientRenderFallbackOnTextMismatch = true;
export const enableLegacyFBSupport = false;
export const enableFilterEmptyStringAttributesDOM = true;
export const enableGetInspectorDataForInstanceInProduction = true;
diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js
index 46f96b7c9d44f..c03dd5ac125d8 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-oss.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js
@@ -87,7 +87,6 @@ export const disableTextareaChildren = false;
export const enableSuspenseAvoidThisFallback = false;
export const enableSuspenseAvoidThisFallbackFizz = false;
export const enableUseEffectEventHook = false;
-export const enableClientRenderFallbackOnTextMismatch = true;
export const enableLegacyFBSupport = false;
export const enableFilterEmptyStringAttributesDOM = true;
export const enableGetInspectorDataForInstanceInProduction = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
index c0430218efdf5..96c4ae8784e92 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
@@ -39,7 +39,6 @@ export const enableSuspenseAvoidThisFallbackFizz = false;
export const enableCPUSuspense = false;
export const enableUseMemoCacheHook = true;
export const enableUseEffectEventHook = false;
-export const enableClientRenderFallbackOnTextMismatch = true;
export const enableComponentStackLocations = true;
export const enableLegacyFBSupport = false;
export const enableFilterEmptyStringAttributesDOM = true;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
index f307540b20c2a..b61b27ea3afb7 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
@@ -45,7 +45,6 @@ export const enableSuspenseAvoidThisFallbackFizz = false;
export const enableCPUSuspense = false;
export const enableUseMemoCacheHook = true;
export const enableUseEffectEventHook = false;
-export const enableClientRenderFallbackOnTextMismatch = true;
export const enableUseRefAccessWarning = false;
export const enableInfiniteRenderLoopDetection = false;
export const enableRenderableContext = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
index cb499f31d7032..7cb09b6a616aa 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
@@ -41,7 +41,6 @@ export const enableSuspenseAvoidThisFallbackFizz = false;
export const enableCPUSuspense = false;
export const enableUseMemoCacheHook = true;
export const enableUseEffectEventHook = false;
-export const enableClientRenderFallbackOnTextMismatch = true;
export const enableComponentStackLocations = true;
export const enableLegacyFBSupport = false;
export const enableFilterEmptyStringAttributesDOM = true;
diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
index 89ef7fae0858a..9d5dccc464fa5 100644
--- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
@@ -30,7 +30,6 @@ export const enableUseDeferredValueInitialArg = __VARIANT__;
export const enableRenderableContext = __VARIANT__;
export const useModernStrictMode = __VARIANT__;
export const enableRefAsProp = __VARIANT__;
-export const enableClientRenderFallbackOnTextMismatch = __VARIANT__;
export const enableNewBooleanProps = __VARIANT__;
export const enableRetryLaneExpiration = __VARIANT__;
export const retryLaneExpirationMs = 5000;
diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js
index 8902b5efac7c6..fc839d73ce3ef 100644
--- a/packages/shared/forks/ReactFeatureFlags.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.www.js
@@ -39,7 +39,6 @@ export const {
useModernStrictMode,
enableRefAsProp,
enableNewBooleanProps,
- enableClientRenderFallbackOnTextMismatch,
} = dynamicFeatureFlags;
// On WWW, __EXPERIMENTAL__ is used for a new modern build.