Skip to content

Commit

Permalink
Support Iterables in Flight (#26313)
Browse files Browse the repository at this point in the history
We support any super type of anything that we can serialize. Meaning
that as long as the Type that's passed through is less precise, it means
that we can encoded it as any subtype and therefore the incoming type
doesn't have to be the subtype in that case. Basically, as long as
you're only passing through an `Iterable<T>` in TypeScript, then you can
pass any `Iterable<T>` and we'll treat it as an array.

For example we support Promises *and* Thenables but both are encoded as
Promises.

We support Arrays and since Arrays are also Iterables, we can support
Iterables.

For @wongmjane
  • Loading branch information
sebmarkbage committed Mar 5, 2023
1 parent f905da2 commit 106ea1c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
28 changes: 28 additions & 0 deletions packages/react-client/src/__tests__/ReactFlight-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,34 @@ describe('ReactFlight', () => {
expect(ReactNoop).toMatchRenderedOutput(<span>Hello, Seb Smith</span>);
});

it('can render an iterable as an array', async () => {
function ItemListClient(props) {
return <span>{props.items}</span>;
}
const ItemList = clientReference(ItemListClient);

function Items() {
const iterable = {
[Symbol.iterator]: function* () {
yield 'A';
yield 'B';
yield 'C';
},
};
return <ItemList items={iterable} />;
}

const model = <Items />;

const transport = ReactNoopFlightServer.render(model);

await act(async () => {
ReactNoop.render(await ReactNoopFlightClient.read(transport));
});

expect(ReactNoop).toMatchRenderedOutput(<span>ABC</span>);
});

it('can render a lazy component as a shared component on the server', async () => {
function SharedComponent({text}) {
return (
Expand Down
7 changes: 7 additions & 0 deletions packages/react-server/src/ReactFlightServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import {
} from './ReactFlightNewContext';

import {
getIteratorFn,
REACT_ELEMENT_TYPE,
REACT_FORWARD_REF_TYPE,
REACT_FRAGMENT_TYPE,
Expand Down Expand Up @@ -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)) {
Expand Down

0 comments on commit 106ea1c

Please sign in to comment.