Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d0f3966

Browse filesBrowse files
authored
Allow functions to be used as module references (#25137)
1 parent 38c5d8a commit d0f3966
Copy full SHA for d0f3966

1 file changed

+54-39Lines changed: 54 additions & 39 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎packages/react-server/src/ReactFlightServer.js‎

Copy file name to clipboardExpand all lines: packages/react-server/src/ReactFlightServer.js
+54-39Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ function attemptResolveElement(
195195
);
196196
}
197197
if (typeof type === 'function') {
198+
if (isModuleReference(type)) {
199+
// This is a reference to a client component.
200+
return [REACT_ELEMENT_TYPE, type, key, props];
201+
}
198202
// This is a server-side component.
199203
return type(props);
200204
} else if (typeof type === 'string') {
@@ -295,6 +299,52 @@ function serializeByRefID(id: number): string {
295299
return '@' + id.toString(16);
296300
}
297301

302+
function serializeModuleReference(
303+
request: Request,
304+
parent: {+[key: string | number]: ReactModel} | $ReadOnlyArray<ReactModel>,
305+
key: string,
306+
moduleReference: ModuleReference<any>,
307+
): string {
308+
const moduleKey: ModuleKey = getModuleKey(moduleReference);
309+
const writtenModules = request.writtenModules;
310+
const existingId = writtenModules.get(moduleKey);
311+
if (existingId !== undefined) {
312+
if (parent[0] === REACT_ELEMENT_TYPE && key === '1') {
313+
// If we're encoding the "type" of an element, we can refer
314+
// to that by a lazy reference instead of directly since React
315+
// knows how to deal with lazy values. This lets us suspend
316+
// on this component rather than its parent until the code has
317+
// loaded.
318+
return serializeByRefID(existingId);
319+
}
320+
return serializeByValueID(existingId);
321+
}
322+
try {
323+
const moduleMetaData: ModuleMetaData = resolveModuleMetaData(
324+
request.bundlerConfig,
325+
moduleReference,
326+
);
327+
request.pendingChunks++;
328+
const moduleId = request.nextChunkId++;
329+
emitModuleChunk(request, moduleId, moduleMetaData);
330+
writtenModules.set(moduleKey, moduleId);
331+
if (parent[0] === REACT_ELEMENT_TYPE && key === '1') {
332+
// If we're encoding the "type" of an element, we can refer
333+
// to that by a lazy reference instead of directly since React
334+
// knows how to deal with lazy values. This lets us suspend
335+
// on this component rather than its parent until the code has
336+
// loaded.
337+
return serializeByRefID(moduleId);
338+
}
339+
return serializeByValueID(moduleId);
340+
} catch (x) {
341+
request.pendingChunks++;
342+
const errorId = request.nextChunkId++;
343+
emitErrorChunk(request, errorId, x);
344+
return serializeByValueID(errorId);
345+
}
346+
}
347+
298348
function escapeStringValue(value: string): string {
299349
if (value[0] === '$' || value[0] === '@') {
300350
// We need to escape $ or @ prefixed strings since we use those to encode
@@ -561,45 +611,7 @@ export function resolveModelToJSON(
561611

562612
if (typeof value === 'object') {
563613
if (isModuleReference(value)) {
564-
const moduleReference: ModuleReference<any> = (value: any);
565-
const moduleKey: ModuleKey = getModuleKey(moduleReference);
566-
const writtenModules = request.writtenModules;
567-
const existingId = writtenModules.get(moduleKey);
568-
if (existingId !== undefined) {
569-
if (parent[0] === REACT_ELEMENT_TYPE && key === '1') {
570-
// If we're encoding the "type" of an element, we can refer
571-
// to that by a lazy reference instead of directly since React
572-
// knows how to deal with lazy values. This lets us suspend
573-
// on this component rather than its parent until the code has
574-
// loaded.
575-
return serializeByRefID(existingId);
576-
}
577-
return serializeByValueID(existingId);
578-
}
579-
try {
580-
const moduleMetaData: ModuleMetaData = resolveModuleMetaData(
581-
request.bundlerConfig,
582-
moduleReference,
583-
);
584-
request.pendingChunks++;
585-
const moduleId = request.nextChunkId++;
586-
emitModuleChunk(request, moduleId, moduleMetaData);
587-
writtenModules.set(moduleKey, moduleId);
588-
if (parent[0] === REACT_ELEMENT_TYPE && key === '1') {
589-
// If we're encoding the "type" of an element, we can refer
590-
// to that by a lazy reference instead of directly since React
591-
// knows how to deal with lazy values. This lets us suspend
592-
// on this component rather than its parent until the code has
593-
// loaded.
594-
return serializeByRefID(moduleId);
595-
}
596-
return serializeByValueID(moduleId);
597-
} catch (x) {
598-
request.pendingChunks++;
599-
const errorId = request.nextChunkId++;
600-
emitErrorChunk(request, errorId, x);
601-
return serializeByValueID(errorId);
602-
}
614+
return serializeModuleReference(request, parent, key, (value: any));
603615
} else if ((value: any).$$typeof === REACT_PROVIDER_TYPE) {
604616
const providerKey = ((value: any): ReactProviderType<any>)._context
605617
._globalName;
@@ -673,6 +685,9 @@ export function resolveModelToJSON(
673685
}
674686

675687
if (typeof value === 'function') {
688+
if (isModuleReference(value)) {
689+
return serializeModuleReference(request, parent, key, (value: any));
690+
}
676691
if (/^on[A-Z]/.test(key)) {
677692
throw new Error(
678693
'Event handlers cannot be passed to client component props. ' +

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.