Skip to content

Commit 64de3b0

Browse files
committed
Throw a better error when Lazy/Promise is used in React.Children (#28280)
We could in theory actually support this case by throwing a Promise when it's used inside a render. Allowing it to be synchronously unwrapped. However, it's a bit sketchy because we officially only support this in the render's child position or in `use()`. Another alternative could be to actually pass the Promise/Lazy to the callback so that you can reason about it and just return it again or even unwrapping with `use()` - at least for the forEach case maybe. DiffTrain build for [e41ee9e](e41ee9e)
1 parent 3b33617 commit 64de3b0

11 files changed

+145
-64
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
d3def47935e8912c197f78c78c97c2476fa1a77a
1+
e41ee9ea70f8998144fdd959ac11fd7a40e4ee20

compiled/facebook-www/React-dev.classic.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ if (__DEV__) {
2424
) {
2525
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
2626
}
27-
var ReactVersion = "18.3.0-www-classic-20554b66";
27+
var ReactVersion = "18.3.0-www-classic-98f29e71";
2828

2929
// ATTENTION
3030
// When adding new symbols to this file,
@@ -2137,6 +2137,13 @@ if (__DEV__) {
21372137
case REACT_ELEMENT_TYPE:
21382138
case REACT_PORTAL_TYPE:
21392139
invokeCallback = true;
2140+
break;
2141+
2142+
case REACT_LAZY_TYPE:
2143+
throw new Error(
2144+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. " +
2145+
"We recommend not iterating over children and just rendering them plain."
2146+
);
21402147
}
21412148
}
21422149
}
@@ -2250,6 +2257,14 @@ if (__DEV__) {
22502257
} else if (type === "object") {
22512258
// eslint-disable-next-line react-internal/safe-string-coercion
22522259
var childrenString = String(children);
2260+
2261+
if (typeof children.then === "function") {
2262+
throw new Error(
2263+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. " +
2264+
"We recommend not iterating over children and just rendering them plain."
2265+
);
2266+
}
2267+
22532268
throw new Error(
22542269
"Objects are not valid as a React child (found: " +
22552270
(childrenString === "[object Object]"

compiled/facebook-www/React-dev.modern.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ if (__DEV__) {
2424
) {
2525
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
2626
}
27-
var ReactVersion = "18.3.0-www-modern-94139f2c";
27+
var ReactVersion = "18.3.0-www-modern-33733854";
2828

2929
// ATTENTION
3030
// When adding new symbols to this file,
@@ -2102,6 +2102,13 @@ if (__DEV__) {
21022102
case REACT_ELEMENT_TYPE:
21032103
case REACT_PORTAL_TYPE:
21042104
invokeCallback = true;
2105+
break;
2106+
2107+
case REACT_LAZY_TYPE:
2108+
throw new Error(
2109+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. " +
2110+
"We recommend not iterating over children and just rendering them plain."
2111+
);
21052112
}
21062113
}
21072114
}
@@ -2215,6 +2222,14 @@ if (__DEV__) {
22152222
} else if (type === "object") {
22162223
// eslint-disable-next-line react-internal/safe-string-coercion
22172224
var childrenString = String(children);
2225+
2226+
if (typeof children.then === "function") {
2227+
throw new Error(
2228+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. " +
2229+
"We recommend not iterating over children and just rendering them plain."
2230+
);
2231+
}
2232+
22182233
throw new Error(
22192234
"Objects are not valid as a React child (found: " +
22202235
(childrenString === "[object Object]"

compiled/facebook-www/React-prod.classic.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
180180
case REACT_ELEMENT_TYPE:
181181
case REACT_PORTAL_TYPE:
182182
invokeCallback = !0;
183+
break;
184+
case REACT_LAZY_TYPE:
185+
throw Error(
186+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. We recommend not iterating over children and just rendering them plain."
187+
);
183188
}
184189
}
185190
if (invokeCallback)
@@ -244,17 +249,20 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
244249
nextName,
245250
callback
246251
));
247-
else if ("object" === type)
248-
throw (
249-
((array = String(children)),
250-
Error(
251-
"Objects are not valid as a React child (found: " +
252-
("[object Object]" === array
253-
? "object with keys {" + Object.keys(children).join(", ") + "}"
254-
: array) +
255-
"). If you meant to render a collection of children, use an array instead."
256-
))
252+
else if ("object" === type) {
253+
array = String(children);
254+
if ("function" === typeof children.then)
255+
throw Error(
256+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. We recommend not iterating over children and just rendering them plain."
257+
);
258+
throw Error(
259+
"Objects are not valid as a React child (found: " +
260+
("[object Object]" === array
261+
? "object with keys {" + Object.keys(children).join(", ") + "}"
262+
: array) +
263+
"). If you meant to render a collection of children, use an array instead."
257264
);
265+
}
258266
return invokeCallback;
259267
}
260268
function mapChildren(children, func, context) {
@@ -570,4 +578,4 @@ exports.useSyncExternalStore = function (
570578
exports.useTransition = function () {
571579
return ReactCurrentDispatcher.current.useTransition();
572580
};
573-
exports.version = "18.3.0-www-classic-11e5103a";
581+
exports.version = "18.3.0-www-classic-ab0edb2e";

compiled/facebook-www/React-prod.modern.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
151151
case REACT_ELEMENT_TYPE:
152152
case REACT_PORTAL_TYPE:
153153
invokeCallback = !0;
154+
break;
155+
case REACT_LAZY_TYPE:
156+
throw Error(
157+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. We recommend not iterating over children and just rendering them plain."
158+
);
154159
}
155160
}
156161
if (invokeCallback)
@@ -215,17 +220,20 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
215220
nextName,
216221
callback
217222
));
218-
else if ("object" === type)
219-
throw (
220-
((array = String(children)),
221-
Error(
222-
"Objects are not valid as a React child (found: " +
223-
("[object Object]" === array
224-
? "object with keys {" + Object.keys(children).join(", ") + "}"
225-
: array) +
226-
"). If you meant to render a collection of children, use an array instead."
227-
))
223+
else if ("object" === type) {
224+
array = String(children);
225+
if ("function" === typeof children.then)
226+
throw Error(
227+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. We recommend not iterating over children and just rendering them plain."
228+
);
229+
throw Error(
230+
"Objects are not valid as a React child (found: " +
231+
("[object Object]" === array
232+
? "object with keys {" + Object.keys(children).join(", ") + "}"
233+
: array) +
234+
"). If you meant to render a collection of children, use an array instead."
228235
);
236+
}
229237
return invokeCallback;
230238
}
231239
function mapChildren(children, func, context) {
@@ -562,4 +570,4 @@ exports.useSyncExternalStore = function (
562570
exports.useTransition = function () {
563571
return ReactCurrentDispatcher.current.useTransition();
564572
};
565-
exports.version = "18.3.0-www-modern-72c0502c";
573+
exports.version = "18.3.0-www-modern-17aaa07a";

compiled/facebook-www/React-profiling.classic.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
184184
case REACT_ELEMENT_TYPE:
185185
case REACT_PORTAL_TYPE:
186186
invokeCallback = !0;
187+
break;
188+
case REACT_LAZY_TYPE:
189+
throw Error(
190+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. We recommend not iterating over children and just rendering them plain."
191+
);
187192
}
188193
}
189194
if (invokeCallback)
@@ -248,17 +253,20 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
248253
nextName,
249254
callback
250255
));
251-
else if ("object" === type)
252-
throw (
253-
((array = String(children)),
254-
Error(
255-
"Objects are not valid as a React child (found: " +
256-
("[object Object]" === array
257-
? "object with keys {" + Object.keys(children).join(", ") + "}"
258-
: array) +
259-
"). If you meant to render a collection of children, use an array instead."
260-
))
256+
else if ("object" === type) {
257+
array = String(children);
258+
if ("function" === typeof children.then)
259+
throw Error(
260+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. We recommend not iterating over children and just rendering them plain."
261+
);
262+
throw Error(
263+
"Objects are not valid as a React child (found: " +
264+
("[object Object]" === array
265+
? "object with keys {" + Object.keys(children).join(", ") + "}"
266+
: array) +
267+
"). If you meant to render a collection of children, use an array instead."
261268
);
269+
}
262270
return invokeCallback;
263271
}
264272
function mapChildren(children, func, context) {
@@ -574,7 +582,7 @@ exports.useSyncExternalStore = function (
574582
exports.useTransition = function () {
575583
return ReactCurrentDispatcher.current.useTransition();
576584
};
577-
exports.version = "18.3.0-www-classic-7b6adb38";
585+
exports.version = "18.3.0-www-classic-5d6c9add";
578586
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
579587
"function" ===
580588
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-profiling.modern.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
155155
case REACT_ELEMENT_TYPE:
156156
case REACT_PORTAL_TYPE:
157157
invokeCallback = !0;
158+
break;
159+
case REACT_LAZY_TYPE:
160+
throw Error(
161+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. We recommend not iterating over children and just rendering them plain."
162+
);
158163
}
159164
}
160165
if (invokeCallback)
@@ -219,17 +224,20 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
219224
nextName,
220225
callback
221226
));
222-
else if ("object" === type)
223-
throw (
224-
((array = String(children)),
225-
Error(
226-
"Objects are not valid as a React child (found: " +
227-
("[object Object]" === array
228-
? "object with keys {" + Object.keys(children).join(", ") + "}"
229-
: array) +
230-
"). If you meant to render a collection of children, use an array instead."
231-
))
227+
else if ("object" === type) {
228+
array = String(children);
229+
if ("function" === typeof children.then)
230+
throw Error(
231+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. We recommend not iterating over children and just rendering them plain."
232+
);
233+
throw Error(
234+
"Objects are not valid as a React child (found: " +
235+
("[object Object]" === array
236+
? "object with keys {" + Object.keys(children).join(", ") + "}"
237+
: array) +
238+
"). If you meant to render a collection of children, use an array instead."
232239
);
240+
}
233241
return invokeCallback;
234242
}
235243
function mapChildren(children, func, context) {
@@ -566,7 +574,7 @@ exports.useSyncExternalStore = function (
566574
exports.useTransition = function () {
567575
return ReactCurrentDispatcher.current.useTransition();
568576
};
569-
exports.version = "18.3.0-www-modern-5a1ab6a0";
577+
exports.version = "18.3.0-www-modern-eaf51360";
570578
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
571579
"function" ===
572580
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/ReactDOMTesting-dev.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36343,7 +36343,7 @@ if (__DEV__) {
3634336343
return root;
3634436344
}
3634536345

36346-
var ReactVersion = "18.3.0-www-classic-11e5103a";
36346+
var ReactVersion = "18.3.0-www-classic-ab0edb2e";
3634736347

3634836348
function createPortal$1(
3634936349
children,

compiled/facebook-www/ReactDOMTesting-prod.classic.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17485,7 +17485,7 @@ Internals.Events = [
1748517485
var devToolsConfig$jscomp$inline_1825 = {
1748617486
findFiberByHostInstance: getClosestInstanceFromNode,
1748717487
bundleType: 0,
17488-
version: "18.3.0-www-classic-7b6adb38",
17488+
version: "18.3.0-www-classic-5d6c9add",
1748917489
rendererPackageName: "react-dom"
1749017490
};
1749117491
var internals$jscomp$inline_2194 = {
@@ -17515,7 +17515,7 @@ var internals$jscomp$inline_2194 = {
1751517515
scheduleRoot: null,
1751617516
setRefreshHandler: null,
1751717517
getCurrentFiber: null,
17518-
reconcilerVersion: "18.3.0-www-classic-7b6adb38"
17518+
reconcilerVersion: "18.3.0-www-classic-5d6c9add"
1751917519
};
1752017520
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
1752117521
var hook$jscomp$inline_2195 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -18016,4 +18016,4 @@ exports.useFormStatus = function () {
1801618016
return ReactCurrentDispatcher$2.current.useHostTransitionStatus();
1801718017
throw Error(formatProdErrorMessage(248));
1801818018
};
18019-
exports.version = "18.3.0-www-classic-7b6adb38";
18019+
exports.version = "18.3.0-www-classic-5d6c9add";

compiled/facebook-www/ReactServer-dev.modern.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1815,6 +1815,13 @@ if (__DEV__) {
18151815
case REACT_ELEMENT_TYPE:
18161816
case REACT_PORTAL_TYPE:
18171817
invokeCallback = true;
1818+
break;
1819+
1820+
case REACT_LAZY_TYPE:
1821+
throw new Error(
1822+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. " +
1823+
"We recommend not iterating over children and just rendering them plain."
1824+
);
18181825
}
18191826
}
18201827
}
@@ -1928,6 +1935,14 @@ if (__DEV__) {
19281935
} else if (type === "object") {
19291936
// eslint-disable-next-line react-internal/safe-string-coercion
19301937
var childrenString = String(children);
1938+
1939+
if (typeof children.then === "function") {
1940+
throw new Error(
1941+
"Cannot render an Async Component, Promise or React.Lazy inside React.Children. " +
1942+
"We recommend not iterating over children and just rendering them plain."
1943+
);
1944+
}
1945+
19311946
throw new Error(
19321947
"Objects are not valid as a React child (found: " +
19331948
(childrenString === "[object Object]"
@@ -2568,7 +2583,7 @@ if (__DEV__) {
25682583
console["error"](error);
25692584
};
25702585

2571-
var ReactVersion = "18.3.0-www-modern-d5f8dfac";
2586+
var ReactVersion = "18.3.0-www-modern-de214efc";
25722587

25732588
// Patch fetch
25742589
var Children = {

0 commit comments

Comments
 (0)