Skip to content

Commit b577b26

Browse files
committed
Split IndeterminateComponent out from Lazy
This way we don't have to check the type in a hacky way in the indeterminate path. Also, lets us deal with lazy that resolves to indeterminate and such.
1 parent 8b2f624 commit b577b26

File tree

5 files changed

+104
-79
lines changed

5 files changed

+104
-79
lines changed

packages/react-reconciler/src/ReactCurrentFiber.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
ClassComponent,
1515
HostComponent,
1616
Mode,
17+
LazyComponent,
1718
} from 'shared/ReactWorkTags';
1819
import describeComponentFrame from 'shared/describeComponentFrame';
1920
import getComponentName from 'shared/getComponentName';
@@ -27,6 +28,7 @@ type LifeCyclePhase = 'render' | 'getChildContext';
2728
function describeFiber(fiber: Fiber): string {
2829
switch (fiber.tag) {
2930
case IndeterminateComponent:
31+
case LazyComponent:
3032
case FunctionComponent:
3133
case ClassComponent:
3234
case HostComponent:

packages/react-reconciler/src/ReactFiber.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
SuspenseComponent,
3737
FunctionComponent,
3838
PureComponent,
39+
LazyComponent,
3940
} from 'shared/ReactWorkTags';
4041
import getComponentName from 'shared/getComponentName';
4142

@@ -473,7 +474,7 @@ function createFiberFromElementWithoutDebugInfo(
473474
fiberTag = PureComponent;
474475
break getTag;
475476
case REACT_LAZY_TYPE:
476-
fiberTag = IndeterminateComponent;
477+
fiberTag = LazyComponent;
477478
resolvedType = null;
478479
break getTag;
479480
}

packages/react-reconciler/src/ReactFiberBeginWork.js

Lines changed: 96 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
Profiler,
3232
SuspenseComponent,
3333
PureComponent,
34+
LazyComponent,
3435
} from 'shared/ReactWorkTags';
3536
import {
3637
NoEffect,
@@ -105,7 +106,6 @@ import {
105106
createFiberFromFragment,
106107
createWorkInProgress,
107108
} from './ReactFiber';
108-
import {REACT_LAZY_TYPE} from 'shared/ReactSymbols';
109109

110110
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
111111

@@ -691,7 +691,7 @@ function resolveDefaultProps(Component, baseProps) {
691691
return baseProps;
692692
}
693693

694-
function mountIndeterminateComponent(
694+
function mountLazyComponent(
695695
_current,
696696
workInProgress,
697697
elementType,
@@ -710,85 +710,94 @@ function mountIndeterminateComponent(
710710
}
711711

712712
const props = workInProgress.pendingProps;
713-
let Component;
714-
if (
715-
typeof elementType === 'object' &&
716-
elementType !== null &&
717-
elementType.$$typeof === REACT_LAZY_TYPE
718-
) {
719-
// We can't start a User Timing measurement with correct label yet.
720-
// Cancel and resume right after we know the tag.
721-
cancelWorkTimer(workInProgress);
722-
Component = readLazyComponentType(elementType);
723-
// Store the unwrapped component in the type.
724-
workInProgress.type = Component;
725-
const resolvedTag = (workInProgress.tag = resolveLazyComponentTag(
726-
workInProgress,
727-
Component,
728-
));
729-
startWorkTimer(workInProgress);
730-
const resolvedProps = resolveDefaultProps(Component, props);
731-
let child;
732-
switch (resolvedTag) {
733-
case FunctionComponent: {
734-
child = updateFunctionComponent(
735-
null,
736-
workInProgress,
737-
Component,
738-
resolvedProps,
739-
renderExpirationTime,
740-
);
741-
break;
742-
}
743-
case ClassComponent: {
744-
child = updateClassComponent(
745-
null,
746-
workInProgress,
747-
Component,
748-
resolvedProps,
749-
renderExpirationTime,
750-
);
751-
break;
752-
}
753-
case ForwardRef: {
754-
child = updateForwardRef(
755-
null,
756-
workInProgress,
757-
Component,
758-
resolvedProps,
759-
renderExpirationTime,
760-
);
761-
break;
762-
}
763-
case PureComponent: {
764-
child = updatePureComponent(
765-
null,
766-
workInProgress,
767-
Component,
768-
resolvedProps,
769-
updateExpirationTime,
770-
renderExpirationTime,
771-
);
772-
break;
773-
}
774-
default: {
775-
// This message intentionally doesn't metion ForwardRef or PureComponent
776-
// because the fact that it's a separate type of work is an
777-
// implementation detail.
778-
invariant(
779-
false,
780-
'Element type is invalid. Received a promise that resolves to: %s. ' +
781-
'Promise elements must resolve to a class or function.',
782-
Component,
783-
);
784-
}
713+
// We can't start a User Timing measurement with correct label yet.
714+
// Cancel and resume right after we know the tag.
715+
cancelWorkTimer(workInProgress);
716+
let Component = readLazyComponentType(elementType);
717+
// Store the unwrapped component in the type.
718+
workInProgress.type = Component;
719+
const resolvedTag = (workInProgress.tag = resolveLazyComponentTag(
720+
workInProgress,
721+
Component,
722+
));
723+
startWorkTimer(workInProgress);
724+
const resolvedProps = resolveDefaultProps(Component, props);
725+
let child;
726+
switch (resolvedTag) {
727+
case FunctionComponent: {
728+
child = updateFunctionComponent(
729+
null,
730+
workInProgress,
731+
Component,
732+
resolvedProps,
733+
renderExpirationTime,
734+
);
735+
break;
785736
}
786-
return child;
787-
} else {
788-
workInProgress.type = elementType;
789-
Component = elementType;
737+
case ClassComponent: {
738+
child = updateClassComponent(
739+
null,
740+
workInProgress,
741+
Component,
742+
resolvedProps,
743+
renderExpirationTime,
744+
);
745+
break;
746+
}
747+
case ForwardRef: {
748+
child = updateForwardRef(
749+
null,
750+
workInProgress,
751+
Component,
752+
resolvedProps,
753+
renderExpirationTime,
754+
);
755+
break;
756+
}
757+
case PureComponent: {
758+
child = updatePureComponent(
759+
null,
760+
workInProgress,
761+
Component,
762+
resolvedProps,
763+
updateExpirationTime,
764+
renderExpirationTime,
765+
);
766+
break;
767+
}
768+
default: {
769+
// This message intentionally doesn't metion ForwardRef or PureComponent
770+
// because the fact that it's a separate type of work is an
771+
// implementation detail.
772+
invariant(
773+
false,
774+
'Element type is invalid. Received a promise that resolves to: %s. ' +
775+
'Promise elements must resolve to a class or function.',
776+
Component,
777+
);
778+
}
779+
}
780+
return child;
781+
}
782+
783+
function mountIndeterminateComponent(
784+
_current,
785+
workInProgress,
786+
Component,
787+
renderExpirationTime,
788+
) {
789+
if (_current !== null) {
790+
// An indeterminate component only mounts if it suspended inside a non-
791+
// concurrent tree, in an inconsistent state. We want to tree it like
792+
// a new mount, even though an empty version of it already committed.
793+
// Disconnect the alternate pointers.
794+
_current.alternate = null;
795+
workInProgress.alternate = null;
796+
// Since this is conceptually a new fiber, schedule a Placement effect
797+
workInProgress.effectTag |= Placement;
790798
}
791799

800+
const props = workInProgress.pendingProps;
792801
const unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
793802
const context = getMaskedContext(workInProgress, unmaskedContext);
794803

@@ -1443,6 +1452,15 @@ function beginWork(
14431452
case IndeterminateComponent: {
14441453
const elementType = workInProgress.elementType;
14451454
return mountIndeterminateComponent(
1455+
current,
1456+
workInProgress,
1457+
elementType,
1458+
renderExpirationTime,
1459+
);
1460+
}
1461+
case LazyComponent: {
1462+
const elementType = workInProgress.elementType;
1463+
return mountLazyComponent(
14461464
current,
14471465
workInProgress,
14481466
elementType,

packages/react-reconciler/src/ReactFiberCompleteWork.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
Profiler,
3636
SuspenseComponent,
3737
PureComponent,
38+
LazyComponent,
3839
} from 'shared/ReactWorkTags';
3940
import {Placement, Ref, Update} from 'shared/ReactSideEffectTags';
4041
import invariant from 'shared/invariant';
@@ -536,6 +537,8 @@ function completeWork(
536537
switch (workInProgress.tag) {
537538
case IndeterminateComponent:
538539
break;
540+
case LazyComponent:
541+
break;
539542
case FunctionComponent:
540543
break;
541544
case ClassComponent: {

packages/shared/ReactWorkTags.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ export const ForwardRef = 11;
4343
export const Profiler = 12;
4444
export const SuspenseComponent = 13;
4545
export const PureComponent = 14;
46+
export const LazyComponent = 15;

0 commit comments

Comments
 (0)