@samitouri / QOS-React / commits / c7917fe769

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

salazarm committed Dec 6, 2021 at 12:36 UTC c7917fe76982c499c81be9571de44fe1293ac893
1 file changed +63
packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+63
@@ -3014,4 +3014,67 @@ describe('ReactDOMServerPartialHydration', () => {
3014 );
3015
3016 itHydratesWithoutMismatch('an empty string in class component', TestAppClass);
3017 +
3018 + // @gate enableClientRenderFallbackOnHydrationMismatch
3019 + it('fallback to client render on hydration mismatch at root', async () => {
3020 + let isClient = false;
3021 + let suspend = true;
3022 + let resolve;
3023 + const promise = new Promise((res, rej) => {
3024 + resolve = () => {
3025 + suspend = false;
3026 + res();
3027 + };
3028 + });
3029 + function App() {
3030 + return (
3031 + <>
3032 + <Suspense fallback={<div>Loading</div>}>
3033 + <ChildThatSuspends id={1} />
3034 + </Suspense>
3035 + {isClient ? <span>client</span> : <div>server</div>}
3036 + <Suspense fallback={<div>Loading</div>}>
3037 + <ChildThatSuspends id={2} />
3038 + </Suspense>
3039 + </>
3040 + );
3041 + }
3042 + function ChildThatSuspends({id}) {
3043 + if (isClient && suspend) {
3044 + throw promise;
3045 + }
3046 + return <div>{id}</div>;
3047 + }
3048 +
3049 + const finalHTML = ReactDOMServer.renderToString(<App />);
3050 +
3051 + const container = document.createElement('div');
3052 + document.body.appendChild(container);
3053 + container.innerHTML = finalHTML;
3054 + isClient = true;
3055 +
3056 + expect(() => {
3057 + act(() => {
3058 + ReactDOM.hydrateRoot(container, <App />);
3059 + });
3060 + }).toErrorDev(
3061 + 'Warning: An error occurred during hydration. ' +
3062 + 'The server HTML was replaced with client content in <div>.',
3063 + {withoutStack: true},
3064 + );
3065 +
3066 + // We show fallback state when mismatch happens at root
3067 + expect(container.innerHTML).toEqual(
3068 + '<div>Loading</div><span>client</span><div>Loading</div>',
3069 + );
3070 +
3071 + await act(async () => {
3072 + resolve();
3073 + await promise;
3074 + });
3075 +
3076 + expect(container.innerHTML).toEqual(
3077 + '<div>1</div><span>client</span><div>2</div>',
3078 + );
3079 + });
3080 });