Skip to content

Commit eec50b1

Browse files
authored
[Flight] Only use debug component info for parent stacks (#34431)
1 parent a9410fb commit eec50b1

File tree

2 files changed

+123
-18
lines changed

2 files changed

+123
-18
lines changed

packages/react-client/src/ReactFlightClient.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,13 +1794,21 @@ function transferReferencedDebugInfo(
17941794
existingDebugInfo.push.apply(existingDebugInfo, referencedDebugInfo);
17951795
}
17961796
}
1797-
// We also add it to the initializing chunk since the resolution of that promise is
1798-
// also blocked by these. By adding it to both we can track it even if the array/element
1797+
// We also add the debug info to the initializing chunk since the resolution of that promise is
1798+
// also blocked by the referenced debug info. By adding it to both we can track it even if the array/element
17991799
// is extracted, or if the root is rendered as is.
18001800
if (parentChunk !== null) {
18011801
const parentDebugInfo = parentChunk._debugInfo;
1802-
// $FlowFixMe[method-unbinding]
1803-
parentDebugInfo.push.apply(parentDebugInfo, referencedDebugInfo);
1802+
for (let i = 0; i < referencedDebugInfo.length; ++i) {
1803+
const debugInfoEntry = referencedDebugInfo[i];
1804+
if (debugInfoEntry.name != null) {
1805+
(debugInfoEntry: ReactComponentInfo);
1806+
// We're not transferring Component info since we use Component info
1807+
// in Debug info to fill in gaps between Fibers for the parent stack.
1808+
} else {
1809+
parentDebugInfo.push(debugInfoEntry);
1810+
}
1811+
}
18041812
}
18051813
}
18061814
}

packages/react-client/src/__tests__/ReactFlight-test.js

Lines changed: 111 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2960,13 +2960,6 @@ describe('ReactFlight', () => {
29602960
{
29612961
time: 16,
29622962
},
2963-
{
2964-
env: 'third-party',
2965-
key: null,
2966-
name: 'ThirdPartyAsyncIterableComponent',
2967-
props: {},
2968-
stack: ' in Object.<anonymous> (at **)',
2969-
},
29702963
{
29712964
time: 16,
29722965
},
@@ -2995,13 +2988,6 @@ describe('ReactFlight', () => {
29952988
{
29962989
time: 19,
29972990
},
2998-
{
2999-
env: 'third-party',
3000-
key: null,
3001-
name: 'ThirdPartyAsyncIterableComponent',
3002-
props: {},
3003-
stack: ' in Object.<anonymous> (at **)',
3004-
},
30052991
{time: 19},
30062992
]
30072993
: undefined,
@@ -3847,4 +3833,115 @@ describe('ReactFlight', () => {
38473833

38483834
expect(ReactNoop).toMatchRenderedOutput(<div>not using props</div>);
38493835
});
3836+
3837+
// @gate !__DEV__ || enableComponentPerformanceTrack
3838+
it('produces correct parent stacks', async () => {
3839+
function Container() {
3840+
return ReactServer.createElement('div', null);
3841+
}
3842+
function ContainerParent() {
3843+
return ReactServer.createElement(Container, null);
3844+
}
3845+
function App() {
3846+
return ReactServer.createElement(
3847+
'main',
3848+
null,
3849+
ReactServer.createElement(ContainerParent, null),
3850+
);
3851+
}
3852+
3853+
const transport = ReactNoopFlightServer.render({
3854+
root: ReactServer.createElement(App, null),
3855+
});
3856+
3857+
await act(async () => {
3858+
const {root} = await ReactNoopFlightClient.read(transport);
3859+
3860+
ReactNoop.render(root);
3861+
3862+
expect(root.type).toBe('main');
3863+
if (__DEV__) {
3864+
const div = root.props.children;
3865+
expect(getDebugInfo(div)).toEqual([
3866+
{
3867+
time: 14,
3868+
},
3869+
{
3870+
env: 'Server',
3871+
key: null,
3872+
name: 'ContainerParent',
3873+
owner: {
3874+
env: 'Server',
3875+
key: null,
3876+
name: 'App',
3877+
props: {},
3878+
stack: ' in Object.<anonymous> (at **)',
3879+
},
3880+
props: {},
3881+
stack: ' in App (at **)',
3882+
},
3883+
{
3884+
time: 15,
3885+
},
3886+
{
3887+
env: 'Server',
3888+
key: null,
3889+
name: 'Container',
3890+
owner: {
3891+
env: 'Server',
3892+
key: null,
3893+
name: 'ContainerParent',
3894+
owner: {
3895+
env: 'Server',
3896+
key: null,
3897+
name: 'App',
3898+
props: {},
3899+
stack: ' in Object.<anonymous> (at **)',
3900+
},
3901+
props: {},
3902+
stack: ' in App (at **)',
3903+
},
3904+
props: {},
3905+
stack: ' in ContainerParent (at **)',
3906+
},
3907+
{
3908+
time: 16,
3909+
},
3910+
]);
3911+
expect(getDebugInfo(root)).toEqual([
3912+
{
3913+
time: 12,
3914+
},
3915+
{
3916+
env: 'Server',
3917+
key: null,
3918+
name: 'App',
3919+
props: {},
3920+
stack: ' in Object.<anonymous> (at **)',
3921+
},
3922+
{
3923+
time: 13,
3924+
},
3925+
{
3926+
time: 14,
3927+
},
3928+
{
3929+
time: 15,
3930+
},
3931+
{
3932+
time: 16,
3933+
},
3934+
]);
3935+
} else {
3936+
expect(root._debugInfo).toBe(undefined);
3937+
expect(root._owner).toBe(undefined);
3938+
}
3939+
});
3940+
3941+
expect(ReactNoop).toMatchRenderedOutput(
3942+
<main>
3943+
<div />
3944+
</main>,
3945+
);
3946+
});
38503947
});

0 commit comments

Comments
 (0)