From 57a846126d8534c6b3ff907939021ccaace14979 Mon Sep 17 00:00:00 2001 From: David Dios Date: Mon, 19 Feb 2024 15:45:07 +0000 Subject: [PATCH] fixing multiple suspended child components --- src/index.js | 32 +++++++++++++++++++------------- test/compat/async.test.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/index.js b/src/index.js index 19567c65..d4270283 100644 --- a/src/index.js +++ b/src/index.js @@ -427,9 +427,8 @@ function _renderToString( rendered != null && rendered.type === Fragment && rendered.key == null; rendered = isTopLevelFragment ? rendered.props.children : rendered; - try { - // Recurse into children before invoking the after-diff hook - const str = _renderToString( + const renderChildren = () => + _renderToString( rendered, context, isSvgMode, @@ -437,6 +436,11 @@ function _renderToString( vnode, asyncMode ); + + try { + // Recurse into children before invoking the after-diff hook + const str = renderChildren(); + if (afterDiff) afterDiff(vnode); vnode[PARENT] = undefined; @@ -448,16 +452,18 @@ function _renderToString( if (!error || typeof error.then !== 'function') throw error; - return error.then(() => - _renderToString( - rendered, - context, - isSvgMode, - selectValue, - vnode, - asyncMode - ) - ); + const renderNestedChildren = () => { + try { + return renderChildren(); + } catch (e) { + return e.then( + () => renderChildren(), + () => renderNestedChildren() + ); + } + }; + + return error.then(() => renderNestedChildren()); } } diff --git a/test/compat/async.test.js b/test/compat/async.test.js index 00d4ab04..a6c55fdc 100644 --- a/test/compat/async.test.js +++ b/test/compat/async.test.js @@ -58,4 +58,37 @@ describe('Async renderToString', () => { expect(rendered).to.equal(expected); }); + + it('should render JSX with multiple suspended direct children within a single suspense boundary', async () => { + const { + Suspender: SuspenderOne, + suspended: suspendedOne + } = createSuspender(); + const { + Suspender: SuspenderTwo, + suspended: suspendedTwo + } = createSuspender(); + + const promise = renderToStringAsync( + + ); + + const expected = ``; + + suspendedOne.resolve(); + suspendedTwo.resolve(); + + const rendered = await promise; + + expect(rendered).to.equal(expected); + }); });