Skip to content

Commit 29b9646

Browse files
committed
Refactor resolution to avoid memo hack
Going through createElement isn't quite equivalent for ref and key in props.
1 parent 891e526 commit 29b9646

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

packages/react-server/src/ReactFlightServer.js

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import {
3939
REACT_MEMO_TYPE,
4040
} from 'shared/ReactSymbols';
4141

42-
import * as React from 'react';
4342
import ReactSharedInternals from 'shared/ReactSharedInternals';
4443
import invariant from 'shared/invariant';
4544

@@ -111,10 +110,13 @@ export function createRequest(
111110
return request;
112111
}
113112

114-
function attemptResolveElement(element: React$Element<any>): ReactModel {
115-
const type = element.type;
116-
const props = element.props;
117-
if (element.ref !== null && element.ref !== undefined) {
113+
function attemptResolveElement(
114+
type: any,
115+
key: null | React$Key,
116+
ref: mixed,
117+
props: any,
118+
): ReactModel {
119+
if (ref !== null && ref !== undefined) {
118120
// When the ref moves to the regular props object this will implicitly
119121
// throw for functions. We could probably relax it to a DEV warning for other
120122
// cases.
@@ -128,31 +130,30 @@ function attemptResolveElement(element: React$Element<any>): ReactModel {
128130
return type(props);
129131
} else if (typeof type === 'string') {
130132
// This is a host element. E.g. HTML.
131-
return [REACT_ELEMENT_TYPE, type, element.key, element.props];
133+
return [REACT_ELEMENT_TYPE, type, key, props];
132134
} else if (typeof type === 'symbol') {
133135
if (type === REACT_FRAGMENT_TYPE) {
134136
// For key-less fragments, we add a small optimization to avoid serializing
135137
// it as a wrapper.
136138
// TODO: If a key is specified, we should propagate its key to any children.
137139
// Same as if a server component has a key.
138-
return element.props.children;
140+
return props.children;
139141
}
140142
// This might be a built-in React component. We'll let the client decide.
141143
// Any built-in works as long as its props are serializable.
142-
return [REACT_ELEMENT_TYPE, type, element.key, element.props];
144+
return [REACT_ELEMENT_TYPE, type, key, props];
143145
} else if (type != null && typeof type === 'object') {
144146
if (isModuleReference(type)) {
145147
// This is a reference to a client component.
146-
return [REACT_ELEMENT_TYPE, type, element.key, element.props];
148+
return [REACT_ELEMENT_TYPE, type, key, props];
147149
}
148150
switch (type.$$typeof) {
149151
case REACT_FORWARD_REF_TYPE: {
150152
const render = type.render;
151153
return render(props, undefined);
152154
}
153155
case REACT_MEMO_TYPE: {
154-
const nextChildren = React.createElement(type.type, element.props);
155-
return attemptResolveElement(nextChildren);
156+
return attemptResolveElement(type.type, key, ref, props);
156157
}
157158
}
158159
}
@@ -389,7 +390,12 @@ export function resolveModelToJSON(
389390
const element: React$Element<any> = (value: any);
390391
try {
391392
// Attempt to render the server component.
392-
value = attemptResolveElement(element);
393+
value = attemptResolveElement(
394+
element.type,
395+
element.key,
396+
element.ref,
397+
element.props,
398+
);
393399
} catch (x) {
394400
if (typeof x === 'object' && x !== null && typeof x.then === 'function') {
395401
// Something suspended, we'll need to create a new segment and resolve it later.
@@ -600,7 +606,12 @@ function retrySegment(request: Request, segment: Segment): void {
600606
// Doing this here lets us reuse this same segment if the next component
601607
// also suspends.
602608
segment.query = () => value;
603-
value = attemptResolveElement(element);
609+
value = attemptResolveElement(
610+
element.type,
611+
element.key,
612+
element.ref,
613+
element.props,
614+
);
604615
}
605616
const processedChunk = processModelChunk(request, segment.id, value);
606617
request.completedJSONChunks.push(processedChunk);

0 commit comments

Comments
 (0)