Skip to content

Commit

Permalink
fixing multiple suspended child components (#335)
Browse files Browse the repository at this point in the history
  • Loading branch information
dios-david authored Feb 20, 2024
1 parent c57b230 commit cf81587
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 13 deletions.
32 changes: 19 additions & 13 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -438,16 +438,20 @@ 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,
selectValue,
vnode,
asyncMode
);

try {
// Recurse into children before invoking the after-diff hook
const str = renderChildren();

if (afterDiff) afterDiff(vnode);
vnode[PARENT] = undefined;

Expand All @@ -459,16 +463,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());
}
}

Expand Down
43 changes: 43 additions & 0 deletions test/compat/async.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,47 @@ 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 {
Suspender: SuspenderThree,
suspended: suspendedThree
} = createSuspender();

const promise = renderToStringAsync(
<ul>
<Suspense fallback={null}>
<SuspenderOne>
<li>one</li>
</SuspenderOne>
<Suspense fallback={null}>
<SuspenderTwo>
<li>two</li>
</SuspenderTwo>
</Suspense>
<SuspenderThree>
<li>three</li>
</SuspenderThree>
</Suspense>
</ul>
);

const expected = `<ul><li>one</li><li>two</li><li>three</li></ul>`;

suspendedOne.resolve();
suspendedTwo.resolve();
suspendedThree.resolve();

const rendered = await promise;

expect(rendered).to.equal(expected);
});
});

0 comments on commit cf81587

Please sign in to comment.