From 6e928c8db556c2693814ed2a4d4b00070bce2242 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sat, 5 Jun 2021 15:15:11 +0100 Subject: [PATCH] Add a failing test for Suspense hydration --- ...DOMServerPartialHydration-test.internal.js | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js index 8e3c99ccc283c..1f4a07290b157 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js @@ -160,6 +160,59 @@ describe('ReactDOMServerPartialHydration', () => { expect(ref.current).toBe(span); }); + it('can hydrate siblings of a suspended component without errors', async () => { + let suspend = false; + let resolve; + const promise = new Promise(resolvePromise => (resolve = resolvePromise)); + function Child() { + if (suspend) { + throw promise; + } else { + return 'Hello'; + } + } + + function App() { + return ( + + + + + + + ); + } + + // First we render the final HTML. With the streaming renderer + // this may have suspense points on the server but here we want + // to test the completed HTML. Don't suspend on the server. + suspend = false; + const finalHTML = ReactDOMServer.renderToString(); + + const container = document.createElement('div'); + container.innerHTML = finalHTML; + expect(container.textContent).toBe('HelloHello'); + + // On the client we don't have all data yet but we want to start + // hydrating anyway. + suspend = true; + const root = ReactDOM.createRoot(container, {hydrate: true}); + root.render(); + Scheduler.unstable_flushAll(); + jest.runAllTimers(); + // Expect the server-generated HTML to stay intact. + expect(container.textContent).toBe('HelloHello'); + + // Resolving the promise should continue hydration + suspend = false; + resolve(); + await promise; + Scheduler.unstable_flushAll(); + jest.runAllTimers(); + // Hydration should not change anything. + expect(container.textContent).toBe('HelloHello'); + }); + it('calls the hydration callbacks after hydration or deletion', async () => { let suspend = false; let resolve;