From d38630f5b3f7835fc9240dd7de2a91c330c0e974 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 d7cec67f5bfa9..125ff2cfb9d49 100644 --- a/packages/react-client/src/__tests__/ReactFlight-test.js +++ b/packages/react-client/src/__tests__/ReactFlight-test.js @@ -166,6 +166,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 20800530b831c..b860a7a5c480f 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, @@ -1053,6 +1054,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)) {