Skip to content

Commit 0618f8b

Browse files
committed
enhance resolveElement to handle async components in array-valued props
1 parent 707a6a9 commit 0618f8b

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

src/__tests__/renderAsync.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,32 @@ describe('renderAsync', () => {
260260
expect(screen.getByTestId('content')).toHaveTextContent('Content')
261261
})
262262

263+
test('resolves async components in array-valued props', async () => {
264+
async function AsyncTab({label}) {
265+
return <li data-testid={`tab-${label}`}>{label}</li>
266+
}
267+
268+
function SyncTab({label}) {
269+
return <li data-testid={`tab-${label}`}>{label}</li>
270+
}
271+
272+
function TabBar({tabs}) {
273+
return <ul data-testid="tab-bar">{tabs}</ul>
274+
}
275+
276+
await renderAsync(
277+
<TabBar
278+
tabs={[
279+
<AsyncTab key="async" label="async" />,
280+
<SyncTab key="sync" label="sync" />,
281+
]}
282+
/>,
283+
)
284+
expect(screen.getByTestId('tab-bar')).toBeInTheDocument()
285+
expect(screen.getByTestId('tab-async')).toHaveTextContent('async')
286+
expect(screen.getByTestId('tab-sync')).toHaveTextContent('sync')
287+
})
288+
263289
test('passes through non-element objects in children unchanged', async () => {
264290
function Container({children}) {
265291
return <div data-testid="container">{String(children)}</div>

src/pure.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,11 @@ async function resolveElement(element) {
343343

344344
if (typeof element.type === 'function' && isAsyncFunction(element.type)) {
345345
const resolved = await element.type({...element.props})
346-
return resolveElement(resolved)
346+
const resolvedElement = await resolveElement(resolved)
347+
if (element.key != null && React.isValidElement(resolvedElement)) {
348+
return React.cloneElement(resolvedElement, {key: element.key})
349+
}
350+
return resolvedElement
347351
}
348352

349353
return resolveElementProps(element)
@@ -364,6 +368,12 @@ async function resolveElementProps(element) {
364368
changed: resolved !== value,
365369
}))
366370
}
371+
if (Array.isArray(value) && value.some(React.isValidElement)) {
372+
return resolveElement(value).then(resolved => ({
373+
value: resolved,
374+
changed: resolved !== value,
375+
}))
376+
}
367377
return {value, changed: false}
368378
}),
369379
)

0 commit comments

Comments
 (0)