Skip to content

Commit d821778

Browse files
authored
Accept promise as element type (#13397)
* Accept promise as element type On the initial render, the element will suspend as if a promise were thrown from inside the body of the unresolved component. Siblings should continue rendering and if the parent is a Placeholder, the promise should be captured by that Placeholder. When the promise resolves, rendering resumes. If the resolved value has a `default` property, it is assumed to be the default export of an ES module, and we use that as the component type. If it does not have a `default` property, we use the resolved value itself. The resolved value is stored as an expando on the promise/thenable. * Use special types of work for lazy components Because reconciliation is a hot path, this adds ClassComponentLazy, FunctionalComponentLazy, and ForwardRefLazy as special types of work. The other types are not supported, but wouldn't be placed into a separate module regardless. * Resolve defaultProps for lazy types * Remove some calls to isContextProvider isContextProvider checks the fiber tag, but it's typically called after we've already refined the type of work. We should get rid of it. I removed some of them in the previous commit, and deleted a few more in this one. I left a few behind because the remaining ones would require additional refactoring that feels outside the scope of this PR. * Remove getLazyComponentTypeIfResolved * Return baseProps instead of null The caller compares the result to baseProps to see if anything changed. * Avoid redundant checks by inlining getFiberTagFromObjectType * Move tag resolution to ReactFiber module * Pass next props to update* functions We should do this with all types of work in the future. * Refine component type before pushing/popping context Removes unnecessary checks. * Replace all occurrences of _reactResult with helper * Move shared thenable logic to `shared` package * Check type of wrapper object before resolving to `default` export * Return resolved tag instead of reassigning
1 parent 8d725d0 commit d821778

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

src/ReactTestRenderer.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import {findCurrentFiberUsingSlowPath} from 'react-reconciler/reflection';
1717
import {
1818
Fragment,
1919
FunctionalComponent,
20+
FunctionalComponentLazy,
2021
ClassComponent,
22+
ClassComponentLazy,
2123
HostComponent,
2224
HostPortal,
2325
HostText,
@@ -27,6 +29,7 @@ import {
2729
Mode,
2830
ForwardRef,
2931
Profiler,
32+
ForwardRefLazy,
3033
} from 'shared/ReactTypeOfWork';
3134
import invariant from 'shared/invariant';
3235
import ReactVersion from 'shared/ReactVersion';
@@ -148,6 +151,17 @@ function toTree(node: ?Fiber) {
148151
instance: node.stateNode,
149152
rendered: childrenToTree(node.child),
150153
};
154+
case ClassComponentLazy: {
155+
const thenable = node.type;
156+
const type = thenable._reactResult;
157+
return {
158+
nodeType: 'component',
159+
type,
160+
props: {...node.memoizedProps},
161+
instance: node.stateNode,
162+
rendered: childrenToTree(node.child),
163+
};
164+
}
151165
case FunctionalComponent:
152166
return {
153167
nodeType: 'component',
@@ -156,6 +170,17 @@ function toTree(node: ?Fiber) {
156170
instance: null,
157171
rendered: childrenToTree(node.child),
158172
};
173+
case FunctionalComponentLazy: {
174+
const thenable = node.type;
175+
const type = thenable._reactResult;
176+
return {
177+
nodeType: 'component',
178+
type: type,
179+
props: {...node.memoizedProps},
180+
instance: node.stateNode,
181+
rendered: childrenToTree(node.child),
182+
};
183+
}
159184
case HostComponent: {
160185
return {
161186
nodeType: 'host',
@@ -173,6 +198,7 @@ function toTree(node: ?Fiber) {
173198
case Mode:
174199
case Profiler:
175200
case ForwardRef:
201+
case ForwardRefLazy:
176202
return childrenToTree(node.child);
177203
default:
178204
invariant(
@@ -198,9 +224,12 @@ function wrapFiber(fiber: Fiber): ReactTestInstance {
198224

199225
const validWrapperTypes = new Set([
200226
FunctionalComponent,
227+
FunctionalComponentLazy,
201228
ClassComponent,
229+
ClassComponentLazy,
202230
HostComponent,
203231
ForwardRef,
232+
ForwardRefLazy,
204233
// Normally skipped, but used when there's more than one root child.
205234
HostRoot,
206235
]);

0 commit comments

Comments
 (0)