Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions packages/react-client/src/ReactFlightClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -1794,13 +1794,21 @@ function transferReferencedDebugInfo(
existingDebugInfo.push.apply(existingDebugInfo, referencedDebugInfo);
}
}
// We also add it to the initializing chunk since the resolution of that promise is
// also blocked by these. By adding it to both we can track it even if the array/element
// We also add the debug info to the initializing chunk since the resolution of that promise is
// also blocked by the referenced debug info. By adding it to both we can track it even if the array/element
// is extracted, or if the root is rendered as is.
if (parentChunk !== null) {
const parentDebugInfo = parentChunk._debugInfo;
// $FlowFixMe[method-unbinding]
parentDebugInfo.push.apply(parentDebugInfo, referencedDebugInfo);
for (let i = 0; i < referencedDebugInfo.length; ++i) {
const debugInfoEntry = referencedDebugInfo[i];
if (debugInfoEntry.name != null) {
(debugInfoEntry: ReactComponentInfo);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double checked that Flow starts erroring once we add another union member to ReactDebugInfoEntry with a name property. This type assertion ensures that future us needs to decide whether a new kind of ReactDebugInfoEntry with name should be transferred or not.

// We're not transferring Component info since we use Component info
// in Debug info to fill in gaps between Fibers for the parent stack.
} else {
parentDebugInfo.push(debugInfoEntry);
}
}
}
}
}
Expand Down
125 changes: 111 additions & 14 deletions packages/react-client/src/__tests__/ReactFlight-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2960,13 +2960,6 @@ describe('ReactFlight', () => {
{
time: 16,
},
{
env: 'third-party',
key: null,
name: 'ThirdPartyAsyncIterableComponent',
props: {},
stack: ' in Object.<anonymous> (at **)',
},
{
time: 16,
},
Expand Down Expand Up @@ -2995,13 +2988,6 @@ describe('ReactFlight', () => {
{
time: 19,
},
{
env: 'third-party',
key: null,
name: 'ThirdPartyAsyncIterableComponent',
props: {},
stack: ' in Object.<anonymous> (at **)',
},
{time: 19},
]
: undefined,
Expand Down Expand Up @@ -3847,4 +3833,115 @@ describe('ReactFlight', () => {

expect(ReactNoop).toMatchRenderedOutput(<div>not using props</div>);
});

// @gate !__DEV__ || enableComponentPerformanceTrack
it('produces correct parent stacks', async () => {
function Container() {
return ReactServer.createElement('div', null);
}
function ContainerParent() {
return ReactServer.createElement(Container, null);
}
function App() {
return ReactServer.createElement(
'main',
null,
ReactServer.createElement(ContainerParent, null),
);
}

const transport = ReactNoopFlightServer.render({
root: ReactServer.createElement(App, null),
});

await act(async () => {
const {root} = await ReactNoopFlightClient.read(transport);

ReactNoop.render(root);

expect(root.type).toBe('main');
if (__DEV__) {
const div = root.props.children;
expect(getDebugInfo(div)).toEqual([
{
time: 14,
},
{
env: 'Server',
key: null,
name: 'ContainerParent',
owner: {
env: 'Server',
key: null,
name: 'App',
props: {},
stack: ' in Object.<anonymous> (at **)',
},
props: {},
stack: ' in App (at **)',
},
{
time: 15,
},
{
env: 'Server',
key: null,
name: 'Container',
owner: {
env: 'Server',
key: null,
name: 'ContainerParent',
owner: {
env: 'Server',
key: null,
name: 'App',
props: {},
stack: ' in Object.<anonymous> (at **)',
},
props: {},
stack: ' in App (at **)',
},
props: {},
stack: ' in ContainerParent (at **)',
},
{
time: 16,
},
]);
expect(getDebugInfo(root)).toEqual([
{
time: 12,
},
{
env: 'Server',
key: null,
name: 'App',
props: {},
stack: ' in Object.<anonymous> (at **)',
},
{
time: 13,
},
{
time: 14,
},
{
time: 15,
},
{
time: 16,
},
]);
} else {
expect(root._debugInfo).toBe(undefined);
expect(root._owner).toBe(undefined);
}
});

expect(ReactNoop).toMatchRenderedOutput(
<main>
<div />
</main>,
);
});
});
Loading