Skip to content

Commit 6e928c8

Browse files
committed
Add a failing test for Suspense hydration
1 parent 23c8095 commit 6e928c8

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,59 @@ describe('ReactDOMServerPartialHydration', () => {
160160
expect(ref.current).toBe(span);
161161
});
162162

163+
it('can hydrate siblings of a suspended component without errors', async () => {
164+
let suspend = false;
165+
let resolve;
166+
const promise = new Promise(resolvePromise => (resolve = resolvePromise));
167+
function Child() {
168+
if (suspend) {
169+
throw promise;
170+
} else {
171+
return 'Hello';
172+
}
173+
}
174+
175+
function App() {
176+
return (
177+
<Suspense fallback="Loading...">
178+
<Child />
179+
<Suspense fallback="Loading...">
180+
<Child />
181+
</Suspense>
182+
</Suspense>
183+
);
184+
}
185+
186+
// First we render the final HTML. With the streaming renderer
187+
// this may have suspense points on the server but here we want
188+
// to test the completed HTML. Don't suspend on the server.
189+
suspend = false;
190+
const finalHTML = ReactDOMServer.renderToString(<App />);
191+
192+
const container = document.createElement('div');
193+
container.innerHTML = finalHTML;
194+
expect(container.textContent).toBe('HelloHello');
195+
196+
// On the client we don't have all data yet but we want to start
197+
// hydrating anyway.
198+
suspend = true;
199+
const root = ReactDOM.createRoot(container, {hydrate: true});
200+
root.render(<App />);
201+
Scheduler.unstable_flushAll();
202+
jest.runAllTimers();
203+
// Expect the server-generated HTML to stay intact.
204+
expect(container.textContent).toBe('HelloHello');
205+
206+
// Resolving the promise should continue hydration
207+
suspend = false;
208+
resolve();
209+
await promise;
210+
Scheduler.unstable_flushAll();
211+
jest.runAllTimers();
212+
// Hydration should not change anything.
213+
expect(container.textContent).toBe('HelloHello');
214+
});
215+
163216
it('calls the hydration callbacks after hydration or deletion', async () => {
164217
let suspend = false;
165218
let resolve;

0 commit comments

Comments
 (0)