Skip to content

Commit

Permalink
Add test case for hydration warning suppression
Browse files Browse the repository at this point in the history
In facebook#24404 a test case was added for supressing hydration warnings if a preceding component suspends. The test case showed that hydration warnings would still emit after resolution but it did not include a test case for when the resolution led to a complete hydration without errors. This commit adds the additional test case demonstrating that no warnings or Errors are observed if hydration completes successfully after suspended component resolution
  • Loading branch information
gnoff committed Apr 25, 2022
1 parent bd4784c commit 26e25bd
Showing 1 changed file with 77 additions and 1 deletion.
78 changes: 77 additions & 1 deletion packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
Expand Up @@ -2851,7 +2851,7 @@ describe('ReactDOMFizzServer', () => {
});

// @gate experimental && enableClientRenderFallbackOnTextMismatch
it('#24384: Suspending should halt hydration warnings while still allowing siblings to warm up', async () => {
it('#24384: Suspending should halt hydration warnings but still emit hydration warnings after unsuspending if mismatches are genuine', async () => {
const makeApp = () => {
let resolve, resolved;
const promise = new Promise(r => {
Expand Down Expand Up @@ -2940,6 +2940,82 @@ describe('ReactDOMFizzServer', () => {
expect(Scheduler).toFlushAndYield([]);
});

// @gate experimental && enableClientRenderFallbackOnTextMismatch
it('#24384: Suspending should halt hydration warnings and not emit any if hydration completes successfully after unsuspending', async () => {
const makeApp = () => {
let resolve, resolved;
const promise = new Promise(r => {
resolve = () => {
resolved = true;
return r();
};
});
function ComponentThatSuspends() {
if (!resolved) {
throw promise;
}
return <p>A</p>;
}

const App = () => {
return (
<div>
<Suspense fallback={<h1>Loading...</h1>}>
<ComponentThatSuspends />
<h2 name="hello">world</h2>
</Suspense>
</div>
);
};

return [App, resolve];
};

const [ServerApp, serverResolve] = makeApp();
await act(async () => {
const {pipe} = ReactDOMFizzServer.renderToPipeableStream(<ServerApp />);
pipe(writable);
});
await act(() => {
serverResolve();
});

expect(getVisibleChildren(container)).toEqual(
<div>
<p>A</p>
<h2 name="hello">world</h2>
</div>,
);

const [ClientApp, clientResolve] = makeApp();
ReactDOMClient.hydrateRoot(container, <ClientApp />, {
onRecoverableError(error) {
Scheduler.unstable_yieldValue(
'Logged recoverable error: ' + error.message,
);
},
});
Scheduler.unstable_flushAll();

expect(getVisibleChildren(container)).toEqual(
<div>
<p>A</p>
<h2 name="hello">world</h2>
</div>,
);

// Now that the boundary resolves to it's children the hydration completes and discovers that there is a mismatch requiring
// client-side rendering.
await clientResolve();
expect(Scheduler).toFlushWithoutYielding();
expect(getVisibleChildren(container)).toEqual(
<div>
<p>A</p>
<h2 name="hello">world</h2>
</div>,
);
});

// @gate experimental && enableClientRenderFallbackOnTextMismatch
it('only warns once on hydration mismatch while within a suspense boundary', async () => {
const originalConsoleError = console.error;
Expand Down

0 comments on commit 26e25bd

Please sign in to comment.