From 12e2aee88b9507857121c4d5f1c8b5bbf4aa9cac Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Sun, 5 Mar 2023 01:05:37 -0500 Subject: [PATCH] Support Iterables in Flight --- .../src/__tests__/ReactFlight-test.js | 28 +++++++++++++++++++ .../react-server/src/ReactFlightServer.js | 7 +++++ 2 files changed, 35 insertions(+) diff --git a/packages/react-client/src/__tests__/ReactFlight-test.js b/packages/react-client/src/__tests__/ReactFlight-test.js index 9495b476d6837..b5ca64d9a2e84 100644 --- a/packages/react-client/src/__tests__/ReactFlight-test.js +++ b/packages/react-client/src/__tests__/ReactFlight-test.js @@ -169,6 +169,34 @@ describe('ReactFlight', () => { expect(ReactNoop).toMatchRenderedOutput(Hello, Seb Smith); }); + it('can render an iterable as an array', async () => { + function ItemListClient(props) { + return {props.items}; + } + const ItemList = clientReference(ItemListClient); + + function Items() { + const iterable = { + [Symbol.iterator]: function* () { + yield 'A'; + yield 'B'; + yield 'C'; + }, + }; + return ; + } + + const model = ; + + const transport = ReactNoopFlightServer.render(model); + + await act(async () => { + ReactNoop.render(await ReactNoopFlightClient.read(transport)); + }); + + expect(ReactNoop).toMatchRenderedOutput(ABC); + }); + it('can render a lazy component as a shared component on the server', async () => { function SharedComponent({text}) { return ( diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index 8c46443b3980a..17e1c7aca83c5 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -73,6 +73,7 @@ import { } from './ReactFlightNewContext'; import { + getIteratorFn, REACT_ELEMENT_TYPE, REACT_FORWARD_REF_TYPE, REACT_FRAGMENT_TYPE, @@ -1059,6 +1060,12 @@ export function resolveModelToJSON( } return (undefined: any); } + if (!isArray(value)) { + const iteratorFn = getIteratorFn(value); + if (iteratorFn) { + return Array.from((value: any)); + } + } if (__DEV__) { if (value !== null && !isArray(value)) {