|
7 | 7 | * @flow
|
8 | 8 | */
|
9 | 9 |
|
10 |
| -import type { |
11 |
| - ReactNodeList, |
12 |
| - Thenable, |
13 |
| - PendingThenable, |
14 |
| - FulfilledThenable, |
15 |
| - RejectedThenable, |
16 |
| -} from 'shared/ReactTypes'; |
| 10 | +import type {ReactNodeList} from 'shared/ReactTypes'; |
17 | 11 |
|
18 | 12 | import isArray from 'shared/isArray';
|
19 | 13 | import {
|
@@ -81,68 +75,6 @@ function getElementKey(element: any, index: number): string {
|
81 | 75 | return index.toString(36);
|
82 | 76 | }
|
83 | 77 |
|
84 |
| -function noop() {} |
85 |
| - |
86 |
| -function resolveThenable<T>(thenable: Thenable<T>): T { |
87 |
| - switch (thenable.status) { |
88 |
| - case 'fulfilled': { |
89 |
| - const fulfilledValue: T = thenable.value; |
90 |
| - return fulfilledValue; |
91 |
| - } |
92 |
| - case 'rejected': { |
93 |
| - const rejectedError = thenable.reason; |
94 |
| - throw rejectedError; |
95 |
| - } |
96 |
| - default: { |
97 |
| - if (typeof thenable.status === 'string') { |
98 |
| - // Only instrument the thenable if the status if not defined. If |
99 |
| - // it's defined, but an unknown value, assume it's been instrumented by |
100 |
| - // some custom userspace implementation. We treat it as "pending". |
101 |
| - // Attach a dummy listener, to ensure that any lazy initialization can |
102 |
| - // happen. Flight lazily parses JSON when the value is actually awaited. |
103 |
| - thenable.then(noop, noop); |
104 |
| - } else { |
105 |
| - // This is an uncached thenable that we haven't seen before. |
106 |
| - |
107 |
| - // TODO: Detect infinite ping loops caused by uncached promises. |
108 |
| - |
109 |
| - const pendingThenable: PendingThenable<T> = (thenable: any); |
110 |
| - pendingThenable.status = 'pending'; |
111 |
| - pendingThenable.then( |
112 |
| - fulfilledValue => { |
113 |
| - if (thenable.status === 'pending') { |
114 |
| - const fulfilledThenable: FulfilledThenable<T> = (thenable: any); |
115 |
| - fulfilledThenable.status = 'fulfilled'; |
116 |
| - fulfilledThenable.value = fulfilledValue; |
117 |
| - } |
118 |
| - }, |
119 |
| - (error: mixed) => { |
120 |
| - if (thenable.status === 'pending') { |
121 |
| - const rejectedThenable: RejectedThenable<T> = (thenable: any); |
122 |
| - rejectedThenable.status = 'rejected'; |
123 |
| - rejectedThenable.reason = error; |
124 |
| - } |
125 |
| - }, |
126 |
| - ); |
127 |
| - } |
128 |
| - |
129 |
| - // Check one more time in case the thenable resolved synchronously. |
130 |
| - switch (thenable.status) { |
131 |
| - case 'fulfilled': { |
132 |
| - const fulfilledThenable: FulfilledThenable<T> = (thenable: any); |
133 |
| - return fulfilledThenable.value; |
134 |
| - } |
135 |
| - case 'rejected': { |
136 |
| - const rejectedThenable: RejectedThenable<T> = (thenable: any); |
137 |
| - const rejectedError = rejectedThenable.reason; |
138 |
| - throw rejectedError; |
139 |
| - } |
140 |
| - } |
141 |
| - } |
142 |
| - } |
143 |
| - throw thenable; |
144 |
| -} |
145 |
| - |
146 | 78 | function mapIntoArray(
|
147 | 79 | children: ?ReactNodeList,
|
148 | 80 | array: Array<React$Node>,
|
@@ -175,14 +107,9 @@ function mapIntoArray(
|
175 | 107 | invokeCallback = true;
|
176 | 108 | break;
|
177 | 109 | case REACT_LAZY_TYPE:
|
178 |
| - const payload = (children: any)._payload; |
179 |
| - const init = (children: any)._init; |
180 |
| - return mapIntoArray( |
181 |
| - init(payload), |
182 |
| - array, |
183 |
| - escapedPrefix, |
184 |
| - nameSoFar, |
185 |
| - callback, |
| 110 | + throw new Error( |
| 111 | + 'Cannot render an Async Component, Promise or React.Lazy inside React.Children. ' + |
| 112 | + 'We recommend not iterating over children and just rendering them plain.', |
186 | 113 | );
|
187 | 114 | }
|
188 | 115 | }
|
@@ -285,19 +212,16 @@ function mapIntoArray(
|
285 | 212 | );
|
286 | 213 | }
|
287 | 214 | } else if (type === 'object') {
|
| 215 | + // eslint-disable-next-line react-internal/safe-string-coercion |
| 216 | + const childrenString = String((children: any)); |
| 217 | + |
288 | 218 | if (typeof (children: any).then === 'function') {
|
289 |
| - return mapIntoArray( |
290 |
| - resolveThenable((children: any)), |
291 |
| - array, |
292 |
| - escapedPrefix, |
293 |
| - nameSoFar, |
294 |
| - callback, |
| 219 | + throw new Error( |
| 220 | + 'Cannot render an Async Component, Promise or React.Lazy inside React.Children. ' + |
| 221 | + 'We recommend not iterating over children and just rendering them plain.', |
295 | 222 | );
|
296 | 223 | }
|
297 | 224 |
|
298 |
| - // eslint-disable-next-line react-internal/safe-string-coercion |
299 |
| - const childrenString = String((children: any)); |
300 |
| - |
301 | 225 | throw new Error(
|
302 | 226 | `Objects are not valid as a React child (found: ${
|
303 | 227 | childrenString === '[object Object]'
|
|
0 commit comments