Skip to content

Commit 29d2350

Browse files
committed
Transfer static child validation from lazy component to element
1 parent 771cf48 commit 29d2350

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

packages/react-client/src/ReactFlightClient.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,14 @@ function getTaskName(type: mixed): string {
10741074
}
10751075
}
10761076

1077-
function initializeElement(response: Response, element: any): void {
1077+
function initializeElement(
1078+
response: Response,
1079+
element: any,
1080+
lazyType: null | LazyComponent<
1081+
React$Element<any>,
1082+
SomeChunk<React$Element<any>>,
1083+
>,
1084+
): void {
10781085
if (!__DEV__) {
10791086
return;
10801087
}
@@ -1141,6 +1148,18 @@ function initializeElement(response: Response, element: any): void {
11411148
if (owner !== null) {
11421149
initializeFakeStack(response, owner);
11431150
}
1151+
1152+
// In case the JSX runtime has validated the lazy type as a static child, we
1153+
// need to transfer this information to the element.
1154+
if (
1155+
lazyType &&
1156+
lazyType._store &&
1157+
lazyType._store.validated &&
1158+
!element._store.validated
1159+
) {
1160+
element._store.validated = lazyType._store.validated;
1161+
}
1162+
11441163
// TODO: We should be freezing the element but currently, we might write into
11451164
// _debugInfo later. We could move it into _store which remains mutable.
11461165
Object.freeze(element.props);
@@ -1230,7 +1249,7 @@ function createElement(
12301249
handler.reason,
12311250
);
12321251
if (__DEV__) {
1233-
initializeElement(response, element);
1252+
initializeElement(response, element, null);
12341253
// Conceptually the error happened inside this Element but right before
12351254
// it was rendered. We don't have a client side component to render but
12361255
// we can add some DebugInfo to explain that this was conceptually a
@@ -1258,12 +1277,13 @@ function createElement(
12581277
createBlockedChunk(response);
12591278
handler.value = element;
12601279
handler.chunk = blockedChunk;
1280+
const lazyType = createLazyChunkWrapper(blockedChunk);
12611281
if (__DEV__) {
1262-
/// After we have initialized any blocked references, initialize stack etc.
1263-
const init = initializeElement.bind(null, response, element);
1282+
// After we have initialized any blocked references, initialize stack etc.
1283+
const init = initializeElement.bind(null, response, element, lazyType);
12641284
blockedChunk.then(init, init);
12651285
}
1266-
return createLazyChunkWrapper(blockedChunk);
1286+
return lazyType;
12671287
}
12681288
}
12691289
if (__DEV__) {
@@ -1279,6 +1299,7 @@ function createLazyChunkWrapper<T>(
12791299
const lazyType: LazyComponent<T, SomeChunk<T>> = {
12801300
$$typeof: REACT_LAZY_TYPE,
12811301
_payload: chunk,
1302+
_store: {},
12821303
_init: readChunk,
12831304
};
12841305
if (__DEV__) {

packages/react/src/ReactLazy.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ export type LazyComponent<T, P> = {
6060
_payload: P,
6161
_init: (payload: P) => T,
6262
_debugInfo?: null | ReactDebugInfo,
63+
// __DEV__
64+
_store?: {validated: 0 | 1 | 2, ...}, // 0: not validated, 1: validated, 2: force fail
6365
};
6466

6567
function lazyInitializer<T>(payload: Payload<T>): T {

packages/react/src/jsx/ReactJSXElement.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,14 @@ function validateChildKeys(node) {
804804
if (node._store) {
805805
node._store.validated = 1;
806806
}
807+
} else if (isLazyType(node)) {
808+
if (node._payload.status === 'fulfilled') {
809+
if (isValidElement(node._payload.value) && node._payload.value._store) {
810+
node._payload.value._store.validated = 1;
811+
}
812+
} else if (node._store) {
813+
node._store.validated = 1;
814+
}
807815
}
808816
}
809817
}
@@ -822,3 +830,11 @@ export function isValidElement(object) {
822830
object.$$typeof === REACT_ELEMENT_TYPE
823831
);
824832
}
833+
834+
export function isLazyType(object) {
835+
return (
836+
typeof object === 'object' &&
837+
object !== null &&
838+
object.$$typeof === REACT_LAZY_TYPE
839+
);
840+
}

0 commit comments

Comments
 (0)