From 459fca3e17e4e52a4b0de4040e6efd562a519e97 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Mon, 26 Feb 2024 20:52:14 -0500 Subject: [PATCH] Remove enableClientRenderFallbackOnTextMismatch flag --- .../src/client/ReactDOMComponent.js | 19 +-- .../src/__tests__/ReactDOMFizzServer-test.js | 6 +- ...actDOMFizzSuppressHydrationWarning-test.js | 120 ------------------ .../src/__tests__/ReactDOMFloat-test.js | 4 +- .../__tests__/ReactDOMHydrationDiff-test.js | 93 +++++--------- .../ReactDOMServerIntegrationElements-test.js | 16 +-- ...DOMServerPartialHydration-test.internal.js | 2 - .../src/__tests__/ReactRenderDocument-test.js | 27 ++-- .../ReactServerRenderingHydration-test.js | 49 +++---- .../src/ReactFiberCompleteWork.js | 4 +- .../src/ReactFiberHydrationContext.js | 18 +-- packages/shared/ReactFeatureFlags.js | 1 - .../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 - .../forks/ReactFeatureFlags.www-dynamic.js | 1 - .../shared/forks/ReactFeatureFlags.www.js | 1 - 19 files changed, 71 insertions(+), 295 deletions(-) diff --git a/packages/react-dom-bindings/src/client/ReactDOMComponent.js b/packages/react-dom-bindings/src/client/ReactDOMComponent.js index efc7649511dbd..257c3974b87e2 100644 --- a/packages/react-dom-bindings/src/client/ReactDOMComponent.js +++ b/packages/react-dom-bindings/src/client/ReactDOMComponent.js @@ -68,7 +68,6 @@ import sanitizeURL from '../shared/sanitizeURL'; import { enableBigIntSupport, enableCustomElementPropertySupport, - enableClientRenderFallbackOnTextMismatch, enableFormActions, disableIEWorkarounds, enableTrustedTypesIntegration, @@ -349,11 +348,9 @@ export function checkForUnmatchedText( } } - if (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.'); - } + // 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.'); } function noop() {} @@ -2835,16 +2832,6 @@ export function diffHydratedProperties( if (props.suppressHydrationWarning !== true) { checkForUnmatchedText(domElement.textContent, children, shouldWarnDev); } - if (!enableClientRenderFallbackOnTextMismatch) { - // We really should be patching this in the commit phase but since - // this only affects legacy mode hydration which is deprecated anyway - // we can get away with it. - // Host singletons get their children appended and don't use the text - // content mechanism. - if (tag !== 'body') { - domElement.textContent = (children: any); - } - } } } diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index ac7ddfd2f5576..b8d064cad3454 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -4415,7 +4415,6 @@ 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; @@ -4501,7 +4500,6 @@ describe('ReactDOMFizzServer', () => { await waitForAll([]); }); - // @gate enableClientRenderFallbackOnTextMismatch it('only warns once on hydration mismatch while within a suspense boundary', async () => { const originalConsoleError = console.error; const mockError = jest.fn(); @@ -5776,9 +5774,7 @@ describe('ReactDOMFizzServer', () => { } else { expect(errors).toEqual( [ - gate(flags => flags.enableClientRenderFallbackOnTextMismatch) - ? 'Text content does not match server-rendered HTML.' - : null, + '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.', ].filter(Boolean), diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzSuppressHydrationWarning-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzSuppressHydrationWarning-test.js index 3300297b77ee0..d4cefa214c73d 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzSuppressHydrationWarning-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzSuppressHydrationWarning-test.js @@ -130,7 +130,6 @@ describe('ReactDOMFizzServerHydrationWarning', () => { : children; } - // @gate enableClientRenderFallbackOnTextMismatch it('suppresses but does not fix text mismatches with suppressHydrationWarning', async () => { function App({isClient}) { return ( @@ -170,47 +169,6 @@ describe('ReactDOMFizzServerHydrationWarning', () => { ); }); - // @gate !enableClientRenderFallbackOnTextMismatch - it('suppresses and fixes text mismatches with suppressHydrationWarning', async () => { - function App({isClient}) { - return ( -
- - {isClient ? 'Client Text' : 'Server Text'} - - {isClient ? 2 : 1} -
- ); - } - await act(() => { - const {pipe} = ReactDOMFizzServer.renderToPipeableStream( - , - ); - pipe(writable); - }); - expect(getVisibleChildren(container)).toEqual( -
- Server Text - 1 -
, - ); - ReactDOMClient.hydrateRoot(container, , { - onRecoverableError(error) { - // Don't miss a hydration error. There should be none. - Scheduler.log(error.message); - }, - }); - await waitForAll([]); - // The text mismatch should be *silently* fixed. Even in production. - expect(getVisibleChildren(container)).toEqual( -
- Client Text - 2 -
, - ); - }); - - // @gate enableClientRenderFallbackOnTextMismatch it('suppresses but does not fix multiple text node mismatches with suppressHydrationWarning', async () => { function App({isClient}) { return ( @@ -252,48 +210,6 @@ describe('ReactDOMFizzServerHydrationWarning', () => { ); }); - // @gate !enableClientRenderFallbackOnTextMismatch - it('suppresses and fixes multiple text node mismatches with suppressHydrationWarning', async () => { - function App({isClient}) { - return ( -
- - {isClient ? 'Client1' : 'Server1'} - {isClient ? 'Client2' : 'Server2'} - -
- ); - } - await act(() => { - const {pipe} = ReactDOMFizzServer.renderToPipeableStream( - , - ); - pipe(writable); - }); - expect(getVisibleChildren(container)).toEqual( -
- - {'Server1'} - {'Server2'} - -
, - ); - ReactDOMClient.hydrateRoot(container, , { - onRecoverableError(error) { - Scheduler.log(error.message); - }, - }); - await waitForAll([]); - expect(getVisibleChildren(container)).toEqual( -
- - {'Client1'} - {'Client2'} - -
, - ); - }); - it('errors on text-to-element mismatches with suppressHydrationWarning', async () => { function App({isClient}) { return ( @@ -345,7 +261,6 @@ describe('ReactDOMFizzServerHydrationWarning', () => { ); }); - // @gate enableClientRenderFallbackOnTextMismatch it('suppresses but does not fix client-only single text node mismatches with suppressHydrationWarning', async () => { function App({text}) { return ( @@ -386,41 +301,6 @@ describe('ReactDOMFizzServerHydrationWarning', () => { ); }); - // @gate !enableClientRenderFallbackOnTextMismatch - it('suppresses and fixes client-only single text node mismatches with suppressHydrationWarning', async () => { - function App({isClient}) { - return ( -
- - {isClient ? 'Client' : null} - -
- ); - } - await act(() => { - const {pipe} = ReactDOMFizzServer.renderToPipeableStream( - , - ); - pipe(writable); - }); - expect(getVisibleChildren(container)).toEqual( -
- -
, - ); - ReactDOMClient.hydrateRoot(container, , { - onRecoverableError(error) { - Scheduler.log(error.message); - }, - }); - await waitForAll([]); - expect(getVisibleChildren(container)).toEqual( -
- {'Client'} -
, - ); - }); - // TODO: This behavior is not consistent with client-only single text node. it('errors on server-only single text node mismatches with suppressHydrationWarning', async () => { diff --git a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js index 31c1607cc149c..6dc2f33e16dfa 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js @@ -6423,7 +6423,7 @@ body { ); }); - // @gate enableFloat && enableClientRenderFallbackOnTextMismatch + // @gate enableFloat it('retains styles even when a new html, head, and/body mount', async () => { await act(() => { const {pipe} = renderToPipeableStream( @@ -8234,7 +8234,7 @@ background-color: green; ]); }); - // @gate enableFloat && (enableClientRenderFallbackOnTextMismatch || !__DEV__) + // @gate enableFloat it('can render a title before a singleton even if that singleton clears its contents', async () => { await act(() => { const {pipe} = renderToPipeableStream( diff --git a/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js b/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js index 76a8229e5a89f..3be69e79afc53 100644 --- a/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js @@ -89,28 +89,17 @@ describe('ReactDOMServerHydration', () => { ); } - if (gate(flags => flags.enableClientRenderFallbackOnTextMismatch)) { - expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` - [ - "Warning: Text content did not match. Server: "server" Client: "client" - in main (at **) - 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.]", - ] - `); - } else { - expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` - [ - "Warning: Text content did not match. Server: "server" Client: "client" - in main (at **) - in div (at **) - in Mismatch (at **)", - ] - `); - } + expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` + [ + "Warning: Text content did not match. Server: "server" Client: "client" + in main (at **) + 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__ @@ -127,26 +116,16 @@ describe('ReactDOMServerHydration', () => { } /* eslint-disable no-irregular-whitespace */ - if (gate(flags => flags.enableClientRenderFallbackOnTextMismatch)) { - expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` - [ - "Warning: Text content did not match. Server: "This markup contains an nbsp entity:   server text" Client: "This markup contains an nbsp entity:   client text" - 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.]", - ] - `); - } else { - expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` - [ - "Warning: Text content did not match. Server: "This markup contains an nbsp entity:   server text" Client: "This markup contains an nbsp entity:   client text" - in div (at **) - in Mismatch (at **)", - ] - `); - } + expect(testMismatch(Mismatch)).toMatchInlineSnapshot(` + [ + "Warning: Text content did not match. Server: "This markup contains an nbsp entity:   server text" Client: "This markup contains an nbsp entity:   client text" + 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.]", + ] + `); /* eslint-enable no-irregular-whitespace */ }); @@ -397,26 +376,16 @@ describe('ReactDOMServerHydration', () => { function Mismatch({isClient}) { return
{isClient && 'only'}
; } - if (gate(flags => flags.enableClientRenderFallbackOnTextMismatch)) { - 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.]", - ] - `); - } 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 016ee14ca4102..6e36b7964e338 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js @@ -3290,7 +3290,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}
; @@ -3322,7 +3321,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 5474ba5e9985a..16eea72c2ddca 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 56736df064d8f..ebae130c60a6f 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 628dc1755d18f..3d74d6c90b33e 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.js @@ -1320,9 +1320,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 9e55623ab3e70..50c0a802a2ac3 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 { @@ -496,7 +495,7 @@ function prepareToHydrateHostInstance( ); } -function prepareToHydrateHostTextInstance(fiber: Fiber): boolean { +function prepareToHydrateHostTextInstance(fiber: Fiber): void { if (!supportsHydration) { throw new Error( 'Expected prepareToHydrateHostTextInstance() to never be called. ' + @@ -507,13 +506,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; @@ -527,11 +526,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: @@ -547,17 +541,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 2d48410460b87..b6dc9a1734be4 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 enableFormActions = true; export const enableAsyncActions = true; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 67c33d1593310..31f46d79775ea 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -63,7 +63,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 dcc8fd7b95f24..39d8dfc22c150 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -44,7 +44,6 @@ export const enableSuspenseAvoidThisFallbackFizz = false; export const enableCPUSuspense = false; export const enableUseMemoCacheHook = false; export const enableUseEffectEventHook = false; -export const enableClientRenderFallbackOnTextMismatch = true; export const enableComponentStackLocations = false; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index e82f84389e544..581f905c939cf 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -44,7 +44,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 642f2c3f08362..781215c1b0808 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -48,7 +48,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 b276f804cc6bf..929ce7058ae16 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -44,7 +44,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 39fc234de2ad6..0018cc7365011 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 enableRetryLaneExpiration = __VARIANT__; export const retryLaneExpirationMs = 5000; export const syncLaneExpirationMs = 250; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index d8df7644fca52..0336c10ba65f9 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -38,7 +38,6 @@ export const { enableRenderableContext, useModernStrictMode, enableRefAsProp, - enableClientRenderFallbackOnTextMismatch, } = dynamicFeatureFlags; // On WWW, __EXPERIMENTAL__ is used for a new modern build.