Skip to content

Commit 35dcda8

Browse files
committed
Run componentStorage outside the Flight bottom-frame
Otherwise we end up with another stack frame inside of it.
1 parent 8fc04fc commit 35dcda8

File tree

2 files changed

+75
-53
lines changed

2 files changed

+75
-53
lines changed

packages/react-server/src/ReactFlightCallUserSpace.js

+1-35
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,6 @@ import type {ReactClientValue} from './ReactFlightServer';
1515

1616
import {setCurrentOwner} from './flight/ReactFlightCurrentOwner';
1717

18-
import {
19-
supportsComponentStorage,
20-
componentStorage,
21-
} from './ReactFlightServerConfig';
22-
23-
import {enableOwnerStacks} from 'shared/ReactFeatureFlags';
24-
2518
// These indirections exists so we can exclude its stack frame in DEV (and anything below it).
2619
// TODO: Consider marking the whole bundle instead of these boundaries.
2720

@@ -30,38 +23,12 @@ const callComponent = {
3023
Component: (p: Props, arg: void) => R,
3124
props: Props,
3225
componentDebugInfo: ReactComponentInfo,
33-
debugTask: null | ConsoleTask,
3426
): R {
3527
// The secondArg is always undefined in Server Components since refs error early.
3628
const secondArg = undefined;
3729
setCurrentOwner(componentDebugInfo);
3830
try {
39-
if (supportsComponentStorage) {
40-
// Run the component in an Async Context that tracks the current owner.
41-
if (enableOwnerStacks && debugTask) {
42-
return debugTask.run(
43-
// $FlowFixMe[method-unbinding]
44-
componentStorage.run.bind(
45-
componentStorage,
46-
componentDebugInfo,
47-
Component,
48-
props,
49-
secondArg,
50-
),
51-
);
52-
}
53-
return componentStorage.run(
54-
componentDebugInfo,
55-
Component,
56-
props,
57-
secondArg,
58-
);
59-
} else {
60-
if (enableOwnerStacks && debugTask) {
61-
return debugTask.run(Component.bind(null, props, secondArg));
62-
}
63-
return Component(props, secondArg);
64-
}
31+
return Component(props, secondArg);
6532
} finally {
6633
setCurrentOwner(null);
6734
}
@@ -72,7 +39,6 @@ export const callComponentInDEV: <Props, R>(
7239
Component: (p: Props, arg: void) => R,
7340
props: Props,
7441
componentDebugInfo: ReactComponentInfo,
75-
debugTask: null | ConsoleTask,
7642
) => R = __DEV__
7743
? // We use this technique to trick minifiers to preserve the function name.
7844
(callComponent['react-stack-bottom-frame'].bind(callComponent): any)

packages/react-server/src/ReactFlightServer.js

+74-18
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ import {
8080
createHints,
8181
initAsyncDebugInfo,
8282
parseStackTrace,
83+
supportsComponentStorage,
84+
componentStorage,
8385
} from './ReactFlightServerConfig';
8486

8587
import {
@@ -1035,12 +1037,38 @@ function renderFunctionComponent<Props>(
10351037
}
10361038
}
10371039
prepareToUseHooksForComponent(prevThenableState, componentDebugInfo);
1038-
result = callComponentInDEV(
1039-
Component,
1040-
props,
1041-
componentDebugInfo,
1042-
task.debugTask,
1043-
);
1040+
if (supportsComponentStorage) {
1041+
// Run the component in an Async Context that tracks the current owner.
1042+
if (enableOwnerStacks && task.debugTask) {
1043+
result = task.debugTask.run(
1044+
// $FlowFixMe[method-unbinding]
1045+
componentStorage.run.bind(
1046+
componentStorage,
1047+
componentDebugInfo,
1048+
callComponentInDEV,
1049+
Component,
1050+
props,
1051+
componentDebugInfo,
1052+
),
1053+
);
1054+
} else {
1055+
result = componentStorage.run(
1056+
componentDebugInfo,
1057+
callComponentInDEV,
1058+
Component,
1059+
props,
1060+
componentDebugInfo,
1061+
);
1062+
}
1063+
} else {
1064+
if (enableOwnerStacks && task.debugTask) {
1065+
result = task.debugTask.run(
1066+
callComponentInDEV.bind(null, Component, props, componentDebugInfo),
1067+
);
1068+
} else {
1069+
result = callComponentInDEV(Component, props, componentDebugInfo);
1070+
}
1071+
}
10441072
} else {
10451073
prepareToUseHooksForComponent(prevThenableState, null);
10461074
// The secondArg is always undefined in Server Components since refs error early.
@@ -1222,19 +1250,47 @@ function warnForMissingKey(
12221250

12231251
// Call with the server component as the currently rendering component
12241252
// for context.
1225-
callComponentInDEV(
1226-
() => {
1227-
console.error(
1228-
'Each child in a list should have a unique "key" prop.' +
1229-
'%s%s See https://react.dev/link/warning-keys for more information.',
1230-
'',
1231-
'',
1253+
const logKeyError = () => {
1254+
console.error(
1255+
'Each child in a list should have a unique "key" prop.' +
1256+
'%s%s See https://react.dev/link/warning-keys for more information.',
1257+
'',
1258+
'',
1259+
);
1260+
};
1261+
1262+
if (supportsComponentStorage) {
1263+
// Run the component in an Async Context that tracks the current owner.
1264+
if (enableOwnerStacks && debugTask) {
1265+
debugTask.run(
1266+
// $FlowFixMe[method-unbinding]
1267+
componentStorage.run.bind(
1268+
componentStorage,
1269+
componentDebugInfo,
1270+
callComponentInDEV,
1271+
logKeyError,
1272+
null,
1273+
componentDebugInfo,
1274+
),
12321275
);
1233-
},
1234-
null,
1235-
componentDebugInfo,
1236-
debugTask,
1237-
);
1276+
} else {
1277+
componentStorage.run(
1278+
componentDebugInfo,
1279+
callComponentInDEV,
1280+
logKeyError,
1281+
null,
1282+
componentDebugInfo,
1283+
);
1284+
}
1285+
} else {
1286+
if (enableOwnerStacks && debugTask) {
1287+
debugTask.run(
1288+
callComponentInDEV.bind(null, logKeyError, null, componentDebugInfo),
1289+
);
1290+
} else {
1291+
callComponentInDEV(logKeyError, null, componentDebugInfo);
1292+
}
1293+
}
12381294
}
12391295
}
12401296

0 commit comments

Comments
 (0)