Skip to content

Commit b2db1ec

Browse files
committed
Add "use ..." boundary after the change instead of before it
We assume that the first component that has the new environment has a stack which is inside the owner. Since we override the stack of the root owner.
1 parent e6de05f commit b2db1ec

File tree

1 file changed

+39
-50
lines changed

1 file changed

+39
-50
lines changed

packages/react-client/src/ReactFlightClient.js

Lines changed: 39 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ function createElement(
844844
// This owner should ideally have already been initialized to avoid getting
845845
// user stack frames on the stack.
846846
const ownerTask =
847-
owner === null ? null : initializeFakeTask(response, owner, env);
847+
owner === null ? null : initializeFakeTask(response, owner);
848848
if (ownerTask === null) {
849849
const rootTask = response._debugRootTask;
850850
if (rootTask != null) {
@@ -2494,7 +2494,6 @@ function getRootTask(
24942494
function initializeFakeTask(
24952495
response: Response,
24962496
debugInfo: ReactComponentInfo | ReactAsyncInfo | ReactIOInfo,
2497-
childEnvironmentName: string,
24982497
): null | ConsoleTask {
24992498
if (!supportsCreateTask) {
25002499
return null;
@@ -2504,6 +2503,10 @@ function initializeFakeTask(
25042503
// If it's null, we can't initialize a task.
25052504
return null;
25062505
}
2506+
const cachedEntry = debugInfo.debugTask;
2507+
if (cachedEntry !== undefined) {
2508+
return cachedEntry;
2509+
}
25072510

25082511
// Workaround for a bug where Chrome Performance tracking uses the enclosing line/column
25092512
// instead of the callsite. For ReactAsyncInfo/ReactIOInfo, the only thing we're going
@@ -2516,47 +2519,35 @@ function initializeFakeTask(
25162519
const stack = debugInfo.stack;
25172520
const env: string =
25182521
debugInfo.env == null ? response._rootEnvironmentName : debugInfo.env;
2519-
if (env !== childEnvironmentName) {
2522+
const ownerEnv: string =
2523+
debugInfo.owner == null || debugInfo.owner.env == null
2524+
? response._rootEnvironmentName
2525+
: debugInfo.owner.env;
2526+
const ownerTask =
2527+
debugInfo.owner == null
2528+
? null
2529+
: initializeFakeTask(response, debugInfo.owner);
2530+
const taskName =
25202531
// This is the boundary between two environments so we'll annotate the task name.
2521-
// That is unusual so we don't cache it.
2522-
const ownerTask =
2523-
debugInfo.owner == null
2524-
? null
2525-
: initializeFakeTask(response, debugInfo.owner, env);
2526-
return buildFakeTask(
2527-
response,
2528-
ownerTask,
2529-
stack,
2530-
'"use ' + childEnvironmentName.toLowerCase() + '"',
2531-
env,
2532-
useEnclosingLine,
2533-
);
2534-
} else {
2535-
const cachedEntry = debugInfo.debugTask;
2536-
if (cachedEntry !== undefined) {
2537-
return cachedEntry;
2538-
}
2539-
const ownerTask =
2540-
debugInfo.owner == null
2541-
? null
2542-
: initializeFakeTask(response, debugInfo.owner, env);
2543-
// Some unfortunate pattern matching to refine the type.
2544-
const taskName =
2545-
debugInfo.key !== undefined
2532+
// We assume that the stack frame of the entry into the new environment was done
2533+
// from the old environment. So we use the owner's environment as the current.
2534+
env !== ownerEnv
2535+
? '"use ' + env.toLowerCase() + '"'
2536+
: // Some unfortunate pattern matching to refine the type.
2537+
debugInfo.key !== undefined
25462538
? getServerComponentTaskName(((debugInfo: any): ReactComponentInfo))
25472539
: debugInfo.name !== undefined
25482540
? getIOInfoTaskName(((debugInfo: any): ReactIOInfo))
25492541
: getAsyncInfoTaskName(((debugInfo: any): ReactAsyncInfo));
2550-
// $FlowFixMe[cannot-write]: We consider this part of initialization.
2551-
return (debugInfo.debugTask = buildFakeTask(
2552-
response,
2553-
ownerTask,
2554-
stack,
2555-
taskName,
2556-
env,
2557-
useEnclosingLine,
2558-
));
2559-
}
2542+
// $FlowFixMe[cannot-write]: We consider this part of initialization.
2543+
return (debugInfo.debugTask = buildFakeTask(
2544+
response,
2545+
ownerTask,
2546+
stack,
2547+
taskName,
2548+
ownerEnv,
2549+
useEnclosingLine,
2550+
));
25602551
}
25612552

25622553
function buildFakeTask(
@@ -2658,30 +2649,30 @@ function resolveDebugInfo(
26582649
'resolveDebugInfo should never be called in production mode. This is a bug in React.',
26592650
);
26602651
}
2661-
// We eagerly initialize the fake task because this resolving happens outside any
2662-
// render phase so we're not inside a user space stack at this point. If we waited
2663-
// to initialize it when we need it, we might be inside user code.
2664-
const env =
2665-
debugInfo.env === undefined ? response._rootEnvironmentName : debugInfo.env;
26662652
if (debugInfo.stack !== undefined) {
26672653
const componentInfoOrAsyncInfo: ReactComponentInfo | ReactAsyncInfo =
26682654
// $FlowFixMe[incompatible-type]
26692655
debugInfo;
2670-
initializeFakeTask(response, componentInfoOrAsyncInfo, env);
2656+
// We eagerly initialize the fake task because this resolving happens outside any
2657+
// render phase so we're not inside a user space stack at this point. If we waited
2658+
// to initialize it when we need it, we might be inside user code.
2659+
initializeFakeTask(response, componentInfoOrAsyncInfo);
26712660
}
26722661
if (debugInfo.owner === null && response._debugRootOwner != null) {
26732662
const componentInfoOrAsyncInfo: ReactComponentInfo | ReactAsyncInfo =
26742663
// $FlowFixMe: By narrowing `owner` to `null`, we narrowed `debugInfo` to `ReactComponentInfo`
26752664
debugInfo;
26762665
// $FlowFixMe[cannot-write]
26772666
componentInfoOrAsyncInfo.owner = response._debugRootOwner;
2667+
// We clear the parsed stack frames to indicate that it needs to be re-parsed from debugStack.
2668+
// $FlowFixMe[cannot-write]
2669+
componentInfoOrAsyncInfo.stack = null;
26782670
// We override the stack if we override the owner since the stack where the root JSX
26792671
// was created on the server isn't very useful but where the request was made is.
26802672
// $FlowFixMe[cannot-write]
26812673
componentInfoOrAsyncInfo.debugStack = response._debugRootStack;
2682-
// We clear the parsed stack frames to indicate that it needs to be re-parsed from debugStack.
26832674
// $FlowFixMe[cannot-write]
2684-
componentInfoOrAsyncInfo.stack = null;
2675+
componentInfoOrAsyncInfo.debugTask = response._debugRootTask;
26852676
} else if (debugInfo.stack !== undefined) {
26862677
const componentInfoOrAsyncInfo: ReactComponentInfo | ReactAsyncInfo =
26872678
// $FlowFixMe[incompatible-type]
@@ -2741,7 +2732,7 @@ const replayConsoleWithCallStack = {
27412732
bindToConsole(methodName, args, env),
27422733
);
27432734
if (owner != null) {
2744-
const task = initializeFakeTask(response, owner, env);
2735+
const task = initializeFakeTask(response, owner);
27452736
initializeFakeStack(response, owner);
27462737
if (task !== null) {
27472738
task.run(callStack);
@@ -2815,10 +2806,8 @@ function resolveConsoleEntry(
28152806
}
28162807

28172808
function initializeIOInfo(response: Response, ioInfo: ReactIOInfo): void {
2818-
const env =
2819-
ioInfo.env === undefined ? response._rootEnvironmentName : ioInfo.env;
28202809
if (ioInfo.stack !== undefined) {
2821-
initializeFakeTask(response, ioInfo, env);
2810+
initializeFakeTask(response, ioInfo);
28222811
initializeFakeStack(response, ioInfo);
28232812
}
28242813
// Adjust the time to the current environment's time space.

0 commit comments

Comments
 (0)