diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js index 8f67689f835..5b466f2431d 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js @@ -1003,4 +1003,58 @@ describe('ReactDOMServerPartialHydration', () => { let div = container.getElementsByTagName('div')[0]; expect(ref.current).toBe(div); }); + + it('can client render nested boundaries', async () => { + let suspend = false; + let promise = new Promise(() => {}); + let ref = React.createRef(); + + function Child() { + if (suspend) { + throw promise; + } else { + return 'Hello'; + } + } + + function App() { + return ( +
+ + + + + Inner Sibling + + }> + + + Sibling +
+ ); + } + + suspend = true; + let html = ReactDOMServer.renderToString(); + + let container = document.createElement('div'); + container.innerHTML = html + ''; + + let span = container.getElementsByTagName('span')[1]; + + suspend = false; + let root = ReactDOM.unstable_createRoot(container, {hydrate: true}); + root.render(); + Scheduler.unstable_flushAll(); + jest.runAllTimers(); + + expect(ref.current).toBe(span); + expect(span.parentNode).not.toBe(null); + + // It leaves non-React comments alone. + expect(container.lastChild.nodeType).toBe(8); + expect(container.lastChild.data).toBe('unrelated comment'); + }); }); diff --git a/packages/react-dom/src/client/ReactDOMHostConfig.js b/packages/react-dom/src/client/ReactDOMHostConfig.js index 48425c1c8d9..bc2e94f802d 100644 --- a/packages/react-dom/src/client/ReactDOMHostConfig.js +++ b/packages/react-dom/src/client/ReactDOMHostConfig.js @@ -610,15 +610,14 @@ function getNextHydratable(node) { } if (enableSuspenseServerRenderer) { if (nodeType === COMMENT_NODE) { - break; - } - const nodeData = (node: any).data; - if ( - nodeData === SUSPENSE_START_DATA || - nodeData === SUSPENSE_FALLBACK_START_DATA || - nodeData === SUSPENSE_PENDING_START_DATA - ) { - break; + const nodeData = (node: any).data; + if ( + nodeData === SUSPENSE_START_DATA || + nodeData === SUSPENSE_FALLBACK_START_DATA || + nodeData === SUSPENSE_PENDING_START_DATA + ) { + break; + } } } } @@ -691,7 +690,11 @@ export function getNextHydratableInstanceAfterSuspenseInstance( } else { depth--; } - } else if (data === SUSPENSE_START_DATA) { + } else if ( + data === SUSPENSE_START_DATA || + data === SUSPENSE_FALLBACK_START_DATA || + data === SUSPENSE_PENDING_START_DATA + ) { depth++; } }