diff --git a/packages/react-client/src/ReactFlightReplyClient.js b/packages/react-client/src/ReactFlightReplyClient.js index 55bf82184d1c2..99cade0bc1798 100644 --- a/packages/react-client/src/ReactFlightReplyClient.js +++ b/packages/react-client/src/ReactFlightReplyClient.js @@ -15,6 +15,7 @@ import { REACT_ELEMENT_TYPE, REACT_LAZY_TYPE, REACT_PROVIDER_TYPE, + getIteratorFn, } from 'shared/ReactSymbols'; import { @@ -159,6 +160,12 @@ export function processReply( ); return serializePromiseID(promiseId); } + if (!isArray(value)) { + const iteratorFn = getIteratorFn(value); + if (iteratorFn) { + return Array.from((value: any)); + } + } if (__DEV__) { if (value !== null && !isArray(value)) { diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReply-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReply-test.js index 5df671dc65932..c53f8b6f5fc53 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReply-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReply-test.js @@ -17,14 +17,12 @@ global.TextDecoder = require('util').TextDecoder; // let serverExports; let webpackServerMap; -let act; let ReactServerDOMServer; let ReactServerDOMClient; describe('ReactFlightDOMReply', () => { beforeEach(() => { jest.resetModules(); - act = require('internal-test-utils').act; const WebpackMock = require('./utils/WebpackMock'); // serverExports = WebpackMock.serverExports; webpackServerMap = WebpackMock.webpackServerMap; @@ -57,4 +55,24 @@ describe('ReactFlightDOMReply', () => { expect('3' in object.array).toBe(false); expect('prop' in object).toBe(false); }); + + it('can pass an iterable as a reply', async () => { + const body = await ReactServerDOMClient.encodeReply({ + [Symbol.iterator]: function* () { + yield 'A'; + yield 'B'; + yield 'C'; + }, + }); + const iterable = await ReactServerDOMServer.decodeReply( + body, + webpackServerMap, + ); + const items = []; + // eslint-disable-next-line no-for-of-loops/no-for-of-loops + for (const item of iterable) { + items.push(item); + } + expect(items).toEqual(['A', 'B', 'C']); + }); });