Skip to content

Commit b729be0

Browse files
committed
Pass keyPath and implicitSlot as two new contextual values
This keeps track of the keys from parent Server Components that are inherited down.
1 parent 3f90382 commit b729be0

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

packages/react-server/src/ReactFlightServer.js

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ type Task = {
181181
model: ReactClientValue,
182182
ping: () => void,
183183
toJSON: (key: string, value: ReactClientValue) => ReactJSONValue,
184+
keyPath: null | string, // parent server component keys
185+
implicitSlot: boolean, // true if the root server component of this sequence had a null key
184186
context: ContextSnapshot,
185187
thenableState: ThenableState | null,
186188
};
@@ -314,7 +316,14 @@ export function createRequest(
314316
};
315317
request.pendingChunks++;
316318
const rootContext = createRootContext(context);
317-
const rootTask = createTask(request, model, rootContext, abortSet);
319+
const rootTask = createTask(
320+
request,
321+
model,
322+
null,
323+
false,
324+
rootContext,
325+
abortSet,
326+
);
318327
pingedTasks.push(rootTask);
319328
return request;
320329
}
@@ -338,12 +347,18 @@ function createRootContext(
338347

339348
const POP = {};
340349

341-
function serializeThenable(request: Request, thenable: Thenable<any>): number {
350+
function serializeThenable(
351+
request: Request,
352+
task: Task,
353+
thenable: Thenable<any>,
354+
): number {
342355
request.pendingChunks++;
343356
const newTask = createTask(
344357
request,
345358
null,
346-
getActiveContext(),
359+
task.keyPath, // the server component sequence continues through Promise-as-a-child.
360+
task.implicitSlot,
361+
task.context,
347362
request.abortableTasks,
348363
);
349364

@@ -647,6 +662,8 @@ function pingTask(request: Request, task: Task): void {
647662
function createTask(
648663
request: Request,
649664
model: ReactClientValue,
665+
keyPath: null | string,
666+
implicitSlot: boolean,
650667
context: ContextSnapshot,
651668
abortSet: Set<Task>,
652669
): Task {
@@ -659,6 +676,8 @@ function createTask(
659676
id,
660677
status: PENDING,
661678
model,
679+
keyPath,
680+
implicitSlot,
662681
context,
663682
ping: () => pingTask(request, task),
664683
toJSON: function (
@@ -855,7 +874,9 @@ function outlineModel(request: Request, value: ReactClientValue): number {
855874
const newTask = createTask(
856875
request,
857876
value,
858-
getActiveContext(),
877+
null, // The way we use outlining is for reusing an object.
878+
false, // It makes no sense for that use case to be contextual.
879+
rootContextSnapshot, // Therefore we don't pass any contextual information along.
859880
request.abortableTasks,
860881
);
861882
retryTask(request, newTask);
@@ -1016,7 +1037,9 @@ function renderModel(
10161037
const newTask = createTask(
10171038
request,
10181039
task.model,
1019-
getActiveContext(),
1040+
task.keyPath,
1041+
task.implicitSlot,
1042+
task.context,
10201043
request.abortableTasks,
10211044
);
10221045
const ping = newTask.ping;
@@ -1166,7 +1189,7 @@ function renderModelDestructive(
11661189
}
11671190
// We assume that any object with a .then property is a "Thenable" type,
11681191
// or a Promise type. Either of which can be represented by a Promise.
1169-
const promiseId = serializeThenable(request, (value: any));
1192+
const promiseId = serializeThenable(request, task, (value: any));
11701193
writtenObjects.set(value, promiseId);
11711194
return serializePromiseID(promiseId);
11721195
}
@@ -1582,6 +1605,7 @@ function retryTask(request: Request, task: Task): void {
15821605
return;
15831606
}
15841607

1608+
const prevContext = getActiveContext();
15851609
switchContext(task.context);
15861610
try {
15871611
// Track the root so we know that we have to emit this object even though it
@@ -1646,6 +1670,10 @@ function retryTask(request: Request, task: Task): void {
16461670
task.status = ERRORED;
16471671
const digest = logRecoverableError(request, x);
16481672
emitErrorChunk(request, task.id, digest, x);
1673+
} finally {
1674+
if (enableServerContext) {
1675+
switchContext(prevContext);
1676+
}
16491677
}
16501678
}
16511679

0 commit comments

Comments
 (0)