From c7917fe76982c499c81be9571de44fe1293ac893 Mon Sep 17 00:00:00 2001 From: salazarm Date: Mon, 6 Dec 2021 12:36:02 -0500 Subject: [PATCH] Test showing that a mismatch at the root recovers with client render but shows loading state (#22873) * rm console.log * gate test * move test * show fallback state --- ...DOMServerPartialHydration-test.internal.js | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js index d4f3886a1c..780228a427 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js @@ -3014,4 +3014,67 @@ describe('ReactDOMServerPartialHydration', () => { ); itHydratesWithoutMismatch('an empty string in class component', TestAppClass); + + // @gate enableClientRenderFallbackOnHydrationMismatch + it('fallback to client render on hydration mismatch at root', async () => { + let isClient = false; + let suspend = true; + let resolve; + const promise = new Promise((res, rej) => { + resolve = () => { + suspend = false; + res(); + }; + }); + function App() { + return ( + <> + Loading}> + + + {isClient ? client :
server
} + Loading}> + + + + ); + } + function ChildThatSuspends({id}) { + if (isClient && suspend) { + throw promise; + } + return
{id}
; + } + + const finalHTML = ReactDOMServer.renderToString(); + + const container = document.createElement('div'); + document.body.appendChild(container); + container.innerHTML = finalHTML; + isClient = true; + + expect(() => { + act(() => { + ReactDOM.hydrateRoot(container, ); + }); + }).toErrorDev( + 'Warning: An error occurred during hydration. ' + + 'The server HTML was replaced with client content in
.', + {withoutStack: true}, + ); + + // We show fallback state when mismatch happens at root + expect(container.innerHTML).toEqual( + '
Loading
client
Loading
', + ); + + await act(async () => { + resolve(); + await promise; + }); + + expect(container.innerHTML).toEqual( + '
1
client
2
', + ); + }); });