@@ -64,7 +64,6 @@ const {
6464 FunctionalComponent,
6565 ClassComponent,
6666 HostText,
67- HostRoot,
6867 HostPortal,
6968 CoroutineComponent,
7069 YieldComponent,
@@ -75,7 +74,6 @@ const {
7574 NoEffect,
7675 Placement,
7776 Deletion,
78- Err,
7977} = ReactTypeOfSideEffect ;
8078
8179function coerceRef ( current : ?Fiber , element : ReactElement ) {
@@ -1104,10 +1102,31 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
11041102 // not as a fragment. Nested arrays on the other hand will be treated as
11051103 // fragment nodes. Recursion happens at the normal flow.
11061104
1107- if ( ReactFeatureFlags . disableNewFiberFeatures ) {
1105+ const disableNewFiberFeatures = ReactFeatureFlags . disableNewFiberFeatures ;
1106+
1107+ // Handle object types
1108+ if ( typeof newChild === 'object' && newChild !== null ) {
11081109 // Support only the subset of return types that Stack supports. Treat
11091110 // everything else as empty, but log a warning.
1110- if ( typeof newChild === 'object' && newChild !== null ) {
1111+ if ( disableNewFiberFeatures ) {
1112+ switch ( newChild . $$typeof ) {
1113+ case REACT_ELEMENT_TYPE :
1114+ return placeSingleChild ( reconcileSingleElement (
1115+ returnFiber ,
1116+ currentFirstChild ,
1117+ newChild ,
1118+ priority
1119+ ) ) ;
1120+
1121+ case REACT_PORTAL_TYPE :
1122+ return placeSingleChild ( reconcileSinglePortal (
1123+ returnFiber ,
1124+ currentFirstChild ,
1125+ newChild ,
1126+ priority
1127+ ) ) ;
1128+ }
1129+ } else {
11111130 switch ( newChild . $$typeof ) {
11121131 case REACT_ELEMENT_TYPE :
11131132 return placeSingleChild ( reconcileSingleElement (
@@ -1117,6 +1136,22 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
11171136 priority
11181137 ) ) ;
11191138
1139+ case REACT_COROUTINE_TYPE :
1140+ return placeSingleChild ( reconcileSingleCoroutine (
1141+ returnFiber ,
1142+ currentFirstChild ,
1143+ newChild ,
1144+ priority
1145+ ) ) ;
1146+
1147+ case REACT_YIELD_TYPE :
1148+ return placeSingleChild ( reconcileSingleYield (
1149+ returnFiber ,
1150+ currentFirstChild ,
1151+ newChild ,
1152+ priority
1153+ ) ) ;
1154+
11201155 case REACT_PORTAL_TYPE :
11211156 return placeSingleChild ( reconcileSinglePortal (
11221157 returnFiber ,
@@ -1126,44 +1161,37 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
11261161 ) ) ;
11271162 }
11281163 }
1164+ }
11291165
1130- if ( returnFiber . tag === HostRoot ) {
1131- // Top-level only accepts elements or portals
1132- invariant (
1133- // If the root has an error effect, this is an intentional unmount.
1134- // Don't throw an error.
1135- returnFiber . effectTag & Err ,
1136- 'render(): Invalid component element.'
1137- ) ;
1138- } else {
1139- switch ( returnFiber . tag ) {
1140- case ClassComponent : {
1141- if ( __DEV__ ) {
1142- const instance = returnFiber . stateNode ;
1143- if ( instance . render . _isMockFunction ) {
1144- // We allow auto-mocks to proceed as if they're
1145- // returning null.
1146- break ;
1147- }
1166+ if ( disableNewFiberFeatures ) {
1167+ // The new child is not an element. If it's not null or false,
1168+ // and the return fiber is a composite component, throw an error.
1169+ switch ( returnFiber . tag ) {
1170+ case ClassComponent : {
1171+ if ( __DEV__ ) {
1172+ const instance = returnFiber . stateNode ;
1173+ if ( instance . render . _isMockFunction && typeof newChild === 'undefined' ) {
1174+ // We allow auto-mocks to proceed as if they're
1175+ // returning null.
1176+ break ;
11481177 }
11491178 }
1150- // Intentionally fall through to the next case, which handles both
1151- // functions and classes
1152- // eslint-disable-next-lined no-fallthrough
1153- case FunctionalComponent : {
1154- // Composites accept elements, portals, null, or false
1155- const Component = returnFiber . type ;
1156- invariant (
1157- newChild === null || newChild === false ,
1158- '%s.render(): A valid React element (or null) must be ' +
1159- 'returned. You may have returned undefined, an array or some ' +
1160- 'other invalid object.' ,
1161- Component . displayName || Component . name || 'Component'
1162- ) ;
1163- }
1179+ }
1180+ // Intentionally fall through to the next case, which handles both
1181+ // functions and classes
1182+ // eslint-disable-next-lined no-fallthrough
1183+ case FunctionalComponent : {
1184+ // Composites accept elements, portals, null, or false
1185+ const Component = returnFiber . type ;
1186+ invariant (
1187+ newChild === null || newChild === false ,
1188+ '%s(...): A valid React element (or null) must be ' +
1189+ 'returned. You may have returned undefined, an array or some ' +
1190+ 'other invalid object.' ,
1191+ Component . displayName || Component . name || 'Component'
1192+ ) ;
11641193 }
11651194 }
1166- return deleteRemainingChildren ( returnFiber , currentFirstChild ) ;
11671195 }
11681196
11691197 if ( typeof newChild === 'string' || typeof newChild === 'number' ) {
@@ -1175,65 +1203,29 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
11751203 ) ) ;
11761204 }
11771205
1178- if ( typeof newChild === 'object' && newChild !== null ) {
1179- switch ( newChild . $$typeof ) {
1180- case REACT_ELEMENT_TYPE :
1181- return placeSingleChild ( reconcileSingleElement (
1182- returnFiber ,
1183- currentFirstChild ,
1184- newChild ,
1185- priority
1186- ) ) ;
1187-
1188- case REACT_COROUTINE_TYPE :
1189- return placeSingleChild ( reconcileSingleCoroutine (
1190- returnFiber ,
1191- currentFirstChild ,
1192- newChild ,
1193- priority
1194- ) ) ;
1195-
1196- case REACT_YIELD_TYPE :
1197- return placeSingleChild ( reconcileSingleYield (
1198- returnFiber ,
1199- currentFirstChild ,
1200- newChild ,
1201- priority
1202- ) ) ;
1203-
1204- case REACT_PORTAL_TYPE :
1205- return placeSingleChild ( reconcileSinglePortal (
1206- returnFiber ,
1207- currentFirstChild ,
1208- newChild ,
1209- priority
1210- ) ) ;
1211- }
1212-
1213- if ( isArray ( newChild ) ) {
1214- return reconcileChildrenArray (
1215- returnFiber ,
1216- currentFirstChild ,
1217- newChild ,
1218- priority
1219- ) ;
1220- }
1206+ if ( isArray ( newChild ) ) {
1207+ return reconcileChildrenArray (
1208+ returnFiber ,
1209+ currentFirstChild ,
1210+ newChild ,
1211+ priority
1212+ ) ;
1213+ }
12211214
1222- if ( getIteratorFn ( newChild ) ) {
1223- return reconcileChildrenIterator (
1224- returnFiber ,
1225- currentFirstChild ,
1226- newChild ,
1227- priority
1228- ) ;
1229- }
1215+ if ( getIteratorFn ( newChild ) ) {
1216+ return reconcileChildrenIterator (
1217+ returnFiber ,
1218+ currentFirstChild ,
1219+ newChild ,
1220+ priority
1221+ ) ;
12301222 }
12311223
1232- if ( typeof newChild === 'undefined' ) {
1224+ if ( ! disableNewFiberFeatures && typeof newChild === 'undefined' ) {
1225+ // If the new child is undefined, and the return fiber is a composite
1226+ // component, throw an error. If Fiber return types are disabled,
1227+ // we already threw above.
12331228 switch ( returnFiber . tag ) {
1234- case HostRoot :
1235- // TODO: Top-level render
1236- break ;
12371229 case ClassComponent : {
12381230 if ( __DEV__ ) {
12391231 const instance = returnFiber . stateNode ;
0 commit comments