Skip to content

Commit f1657ba

Browse files
authored
Merge branch 'main' into main
2 parents 9c8d33d + 6baff7a commit f1657ba

2 files changed

Lines changed: 70 additions & 2 deletions

File tree

packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,74 @@ describe('ReactFlightDOMEdge', () => {
321321
expect(result).toEqual('<span>Client Component</span>');
322322
});
323323

324+
it('should resolve cyclic references in client component props after two rounds of serialization and deserialization', async () => {
325+
const ClientComponent = clientExports(function ClientComponent({data}) {
326+
return (
327+
<div>{data.self === data ? 'Cycle resolved' : 'Cycle broken'}</div>
328+
);
329+
});
330+
const clientModuleMetadata = webpackMap[ClientComponent.$$id];
331+
const consumerModuleId = 'consumer-' + clientModuleMetadata.id;
332+
const clientReference = Object.defineProperties(ClientComponent, {
333+
$$typeof: {value: Symbol.for('react.client.reference')},
334+
$$id: {value: ClientComponent.$$id},
335+
});
336+
webpackModules[consumerModuleId] = clientReference;
337+
338+
const cyclic = {self: null};
339+
cyclic.self = cyclic;
340+
341+
const stream1 = ReactServerDOMServer.renderToReadableStream(
342+
<React.Fragment key="this-key-is-important-to-repro-a-prior-cycle-serialization-bug">
343+
<ClientComponent data={cyclic} />
344+
</React.Fragment>,
345+
webpackMap,
346+
);
347+
348+
const promise = ReactServerDOMClient.createFromReadableStream(stream1, {
349+
serverConsumerManifest: {
350+
moduleMap: {
351+
[clientModuleMetadata.id]: {
352+
'*': {
353+
id: consumerModuleId,
354+
chunks: [],
355+
name: '*',
356+
},
357+
},
358+
},
359+
moduleLoading: webpackModuleLoading,
360+
serverModuleMap: null,
361+
},
362+
});
363+
364+
const errors = [];
365+
const stream2 = await serverAct(() =>
366+
ReactServerDOMServer.renderToReadableStream(promise, webpackMap, {
367+
onError(error) {
368+
errors.push(error);
369+
},
370+
}),
371+
);
372+
373+
expect(errors).toEqual([]);
374+
375+
const element = await serverAct(() =>
376+
ReactServerDOMClient.createFromReadableStream(stream2, {
377+
serverConsumerManifest: {
378+
moduleMap: null,
379+
moduleLoading: null,
380+
},
381+
}),
382+
);
383+
384+
const ssrStream = await serverAct(() =>
385+
ReactDOMServer.renderToReadableStream(element),
386+
);
387+
const result = await readResult(ssrStream);
388+
389+
expect(result).toBe('<div>Cycle resolved</div>');
390+
});
391+
324392
it('should be able to load a server reference on a consuming server if a mapping exists', async () => {
325393
function greet(name) {
326394
return 'hi, ' + name;

packages/react-server/src/ReactFlightServer.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3622,8 +3622,8 @@ function renderModelDestructive(
36223622
return renderModelDestructive(
36233623
request,
36243624
task,
3625-
emptyRoot,
3626-
'',
3625+
parent,
3626+
parentPropertyName,
36273627
resolvedModel,
36283628
);
36293629
}

0 commit comments

Comments
 (0)