@@ -33,6 +33,7 @@ import {
3333 MemoComponent ,
3434 SimpleMemoComponent ,
3535 LazyComponent ,
36+ IncompleteClassComponent ,
3637} from 'shared/ReactWorkTags' ;
3738import {
3839 NoEffect ,
@@ -762,7 +763,7 @@ function mountLazyComponent(
762763 renderExpirationTime ,
763764) {
764765 if ( _current !== null ) {
765- // An indeterminate component only mounts if it suspended inside a non-
766+ // An lazy component only mounts if it suspended inside a non-
766767 // concurrent tree, in an inconsistent state. We want to tree it like
767768 // a new mount, even though an empty version of it already committed.
768769 // Disconnect the alternate pointers.
@@ -840,6 +841,64 @@ function mountLazyComponent(
840841 return child ;
841842}
842843
844+ function mountIncompleteClassComponent (
845+ _current ,
846+ workInProgress ,
847+ Component ,
848+ nextProps ,
849+ renderExpirationTime ,
850+ ) {
851+ if ( _current !== null ) {
852+ // An incomplete component only mounts if it suspended inside a non-
853+ // concurrent tree, in an inconsistent state. We want to tree it like
854+ // a new mount, even though an empty version of it already committed.
855+ // Disconnect the alternate pointers.
856+ _current . alternate = null ;
857+ workInProgress . alternate = null ;
858+ // Since this is conceptually a new fiber, schedule a Placement effect
859+ workInProgress . effectTag |= Placement ;
860+ }
861+
862+ // Promote the fiber to a class and try rendering again.
863+ workInProgress . tag = ClassComponent ;
864+
865+ // The rest of this function is a fork of `updateClassComponent`
866+
867+ // Push context providers early to prevent context stack mismatches.
868+ // During mounting we don't know the child context yet as the instance doesn't exist.
869+ // We will invalidate the child context in finishClassComponent() right after rendering.
870+ let hasContext ;
871+ if ( isLegacyContextProvider ( Component ) ) {
872+ hasContext = true ;
873+ pushLegacyContextProvider ( workInProgress ) ;
874+ } else {
875+ hasContext = false ;
876+ }
877+ prepareToReadContext ( workInProgress , renderExpirationTime ) ;
878+
879+ constructClassInstance (
880+ workInProgress ,
881+ Component ,
882+ nextProps ,
883+ renderExpirationTime ,
884+ ) ;
885+ mountClassInstance (
886+ workInProgress ,
887+ Component ,
888+ nextProps ,
889+ renderExpirationTime ,
890+ ) ;
891+
892+ return finishClassComponent (
893+ null ,
894+ workInProgress ,
895+ Component ,
896+ true ,
897+ hasContext ,
898+ renderExpirationTime ,
899+ ) ;
900+ }
901+
843902function mountIndeterminateComponent (
844903 _current ,
845904 workInProgress ,
@@ -1654,6 +1713,21 @@ function beginWork(
16541713 renderExpirationTime ,
16551714 ) ;
16561715 }
1716+ case IncompleteClassComponent : {
1717+ const Component = workInProgress . type ;
1718+ const unresolvedProps = workInProgress . pendingProps ;
1719+ const resolvedProps =
1720+ workInProgress . elementType === Component
1721+ ? unresolvedProps
1722+ : resolveDefaultProps ( Component , unresolvedProps ) ;
1723+ return mountIncompleteClassComponent (
1724+ current ,
1725+ workInProgress ,
1726+ Component ,
1727+ resolvedProps ,
1728+ renderExpirationTime ,
1729+ ) ;
1730+ }
16571731 default :
16581732 invariant (
16591733 false ,
0 commit comments