Skip to content

Commit 4c27037

Browse files
authored
Favor fallthrough switch instead of case statements for work tags (#17648)
* Favor fallthrough switch instead of case statements for work tags Currently we're inconsistently handling tags that are only relevant for certain flags. We should throw if the tag is not part of the built feature flags. This should also mean that the case statements can be eliminated. We can achieve this effect by putting the invariant outside of the switch and always early return in the switch. We already do this in beginWork. This PR makes this consistent in other places. * Fail if fundamental/scope tags are discovered without the flag on
1 parent 6fef7c4 commit 4c27037

File tree

3 files changed

+76
-93
lines changed

3 files changed

+76
-93
lines changed

packages/react-reconciler/src/ReactFiberBeginWork.js

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,7 @@ function mountLazyComponent(
10751075
resolvedProps,
10761076
renderExpirationTime,
10771077
);
1078-
break;
1078+
return child;
10791079
}
10801080
case ClassComponent: {
10811081
if (__DEV__) {
@@ -1090,7 +1090,7 @@ function mountLazyComponent(
10901090
resolvedProps,
10911091
renderExpirationTime,
10921092
);
1093-
break;
1093+
return child;
10941094
}
10951095
case ForwardRef: {
10961096
if (__DEV__) {
@@ -1105,7 +1105,7 @@ function mountLazyComponent(
11051105
resolvedProps,
11061106
renderExpirationTime,
11071107
);
1108-
break;
1108+
return child;
11091109
}
11101110
case MemoComponent: {
11111111
if (__DEV__) {
@@ -1130,32 +1130,29 @@ function mountLazyComponent(
11301130
updateExpirationTime,
11311131
renderExpirationTime,
11321132
);
1133-
break;
1133+
return child;
11341134
}
1135-
default: {
1136-
let hint = '';
1137-
if (__DEV__) {
1138-
if (
1139-
Component !== null &&
1140-
typeof Component === 'object' &&
1141-
Component.$$typeof === REACT_LAZY_TYPE
1142-
) {
1143-
hint = ' Did you wrap a component in React.lazy() more than once?';
1144-
}
1145-
}
1146-
// This message intentionally doesn't mention ForwardRef or MemoComponent
1147-
// because the fact that it's a separate type of work is an
1148-
// implementation detail.
1149-
invariant(
1150-
false,
1151-
'Element type is invalid. Received a promise that resolves to: %s. ' +
1152-
'Lazy element type must resolve to a class or function.%s',
1153-
Component,
1154-
hint,
1155-
);
1135+
}
1136+
let hint = '';
1137+
if (__DEV__) {
1138+
if (
1139+
Component !== null &&
1140+
typeof Component === 'object' &&
1141+
Component.$$typeof === REACT_LAZY_TYPE
1142+
) {
1143+
hint = ' Did you wrap a component in React.lazy() more than once?';
11561144
}
11571145
}
1158-
return child;
1146+
// This message intentionally doesn't mention ForwardRef or MemoComponent
1147+
// because the fact that it's a separate type of work is an
1148+
// implementation detail.
1149+
invariant(
1150+
false,
1151+
'Element type is invalid. Received a promise that resolves to: %s. ' +
1152+
'Lazy element type must resolve to a class or function.%s',
1153+
Component,
1154+
hint,
1155+
);
11591156
}
11601157

11611158
function mountIncompleteClassComponent(

packages/react-reconciler/src/ReactFiberCommitWork.js

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -320,14 +320,12 @@ function commitBeforeMutationLifeCycles(
320320
case IncompleteClassComponent:
321321
// Nothing to do for these component types
322322
return;
323-
default: {
324-
invariant(
325-
false,
326-
'This unit of work tag should not have side-effects. This error is ' +
327-
'likely caused by a bug in React. Please file an issue.',
328-
);
329-
}
330323
}
324+
invariant(
325+
false,
326+
'This unit of work tag should not have side-effects. This error is ' +
327+
'likely caused by a bug in React. Please file an issue.',
328+
);
331329
}
332330

333331
function commitHookEffectList(
@@ -420,7 +418,7 @@ function commitLifeCycles(
420418
case ForwardRef:
421419
case SimpleMemoComponent: {
422420
commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
423-
break;
421+
return;
424422
}
425423
case ClassComponent: {
426424
const instance = finishedWork.stateNode;
@@ -629,14 +627,12 @@ function commitLifeCycles(
629627
case FundamentalComponent:
630628
case ScopeComponent:
631629
return;
632-
default: {
633-
invariant(
634-
false,
635-
'This unit of work tag should not have side-effects. This error is ' +
636-
'likely caused by a bug in React. Please file an issue.',
637-
);
638-
}
639630
}
631+
invariant(
632+
false,
633+
'This unit of work tag should not have side-effects. This error is ' +
634+
'likely caused by a bug in React. Please file an issue.',
635+
);
640636
}
641637

642638
function hideOrUnhideAllChildren(finishedWork, isHidden) {
@@ -785,7 +781,7 @@ function commitUnmount(
785781
});
786782
}
787783
}
788-
break;
784+
return;
789785
}
790786
case ClassComponent: {
791787
safelyDetachRef(current);
@@ -843,6 +839,7 @@ function commitUnmount(
843839
if (enableScopeAPI) {
844840
safelyDetachRef(current);
845841
}
842+
return;
846843
}
847844
}
848845
}
@@ -943,14 +940,12 @@ function commitContainer(finishedWork: Fiber) {
943940
replaceContainerChildren(containerInfo, pendingChildren);
944941
return;
945942
}
946-
default: {
947-
invariant(
948-
false,
949-
'This unit of work tag should not have side-effects. This error is ' +
950-
'likely caused by a bug in React. Please file an issue.',
951-
);
952-
}
953943
}
944+
invariant(
945+
false,
946+
'This unit of work tag should not have side-effects. This error is ' +
947+
'likely caused by a bug in React. Please file an issue.',
948+
);
954949
}
955950

956951
function getHostParentFiber(fiber: Fiber): Fiber {
@@ -1408,8 +1403,9 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
14081403
if (enableFundamentalAPI) {
14091404
const fundamentalInstance = finishedWork.stateNode;
14101405
updateFundamentalComponent(fundamentalInstance);
1406+
return;
14111407
}
1412-
return;
1408+
break;
14131409
}
14141410
case ScopeComponent: {
14151411
if (enableScopeAPI) {
@@ -1424,17 +1420,16 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
14241420
updateDeprecatedEventListeners(nextListeners, finishedWork, null);
14251421
}
14261422
}
1423+
return;
14271424
}
1428-
return;
1429-
}
1430-
default: {
1431-
invariant(
1432-
false,
1433-
'This unit of work tag should not have side-effects. This error is ' +
1434-
'likely caused by a bug in React. Please file an issue.',
1435-
);
1425+
break;
14361426
}
14371427
}
1428+
invariant(
1429+
false,
1430+
'This unit of work tag should not have side-effects. This error is ' +
1431+
'likely caused by a bug in React. Please file an issue.',
1432+
);
14381433
}
14391434

14401435
function commitSuspenseComponent(finishedWork: Fiber) {

packages/react-reconciler/src/ReactFiberCompleteWork.js

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -638,18 +638,22 @@ function completeWork(
638638

639639
switch (workInProgress.tag) {
640640
case IndeterminateComponent:
641-
break;
642641
case LazyComponent:
643-
break;
644642
case SimpleMemoComponent:
645643
case FunctionComponent:
646-
break;
644+
case ForwardRef:
645+
case Fragment:
646+
case Mode:
647+
case Profiler:
648+
case ContextConsumer:
649+
case MemoComponent:
650+
return null;
647651
case ClassComponent: {
648652
const Component = workInProgress.type;
649653
if (isLegacyContextProvider(Component)) {
650654
popLegacyContext(workInProgress);
651655
}
652-
break;
656+
return null;
653657
}
654658
case HostRoot: {
655659
popHostContainer(workInProgress);
@@ -670,7 +674,7 @@ function completeWork(
670674
}
671675
}
672676
updateHostContainer(workInProgress);
673-
break;
677+
return null;
674678
}
675679
case HostComponent: {
676680
popHostContext(workInProgress);
@@ -704,7 +708,7 @@ function completeWork(
704708
'caused by a bug in React. Please file an issue.',
705709
);
706710
// This can happen when we abort work.
707-
break;
711+
return null;
708712
}
709713

710714
const currentHostContext = getHostContext();
@@ -783,7 +787,7 @@ function completeWork(
783787
markRef(workInProgress);
784788
}
785789
}
786-
break;
790+
return null;
787791
}
788792
case HostText: {
789793
let newText = newProps;
@@ -817,10 +821,8 @@ function completeWork(
817821
);
818822
}
819823
}
820-
break;
824+
return null;
821825
}
822-
case ForwardRef:
823-
break;
824826
case SuspenseComponent: {
825827
popSuspenseContext(workInProgress);
826828
const nextState: null | SuspenseState = workInProgress.memoizedState;
@@ -961,34 +963,24 @@ function completeWork(
961963
// Always notify the callback
962964
workInProgress.effectTag |= Update;
963965
}
964-
break;
966+
return null;
965967
}
966-
case Fragment:
967-
break;
968-
case Mode:
969-
break;
970-
case Profiler:
971-
break;
972968
case HostPortal:
973969
popHostContainer(workInProgress);
974970
updateHostContainer(workInProgress);
975-
break;
971+
return null;
976972
case ContextProvider:
977973
// Pop provider fiber
978974
popProvider(workInProgress);
979-
break;
980-
case ContextConsumer:
981-
break;
982-
case MemoComponent:
983-
break;
975+
return null;
984976
case IncompleteClassComponent: {
985977
// Same as class component case. I put it down here so that the tags are
986978
// sequential to ensure this switch is compiled to a jump table.
987979
const Component = workInProgress.type;
988980
if (isLegacyContextProvider(Component)) {
989981
popLegacyContext(workInProgress);
990982
}
991-
break;
983+
return null;
992984
}
993985
case SuspenseListComponent: {
994986
popSuspenseContext(workInProgress);
@@ -999,7 +991,7 @@ function completeWork(
999991
if (renderState === null) {
1000992
// We're running in the default, "independent" mode. We don't do anything
1001993
// in this mode.
1002-
break;
994+
return null;
1003995
}
1004996

1005997
let didSuspendAlready =
@@ -1198,7 +1190,7 @@ function completeWork(
11981190
// Do a pass over the next row.
11991191
return next;
12001192
}
1201-
break;
1193+
return null;
12021194
}
12031195
case FundamentalComponent: {
12041196
if (enableFundamentalAPI) {
@@ -1248,6 +1240,7 @@ function completeWork(
12481240
markUpdate(workInProgress);
12491241
}
12501242
}
1243+
return null;
12511244
}
12521245
break;
12531246
}
@@ -1296,19 +1289,17 @@ function completeWork(
12961289
markRef(workInProgress);
12971290
}
12981291
}
1292+
return null;
12991293
}
13001294
break;
13011295
}
1302-
default:
1303-
invariant(
1304-
false,
1305-
'Unknown unit of work tag (%s). This error is likely caused by a bug in ' +
1306-
'React. Please file an issue.',
1307-
workInProgress.tag,
1308-
);
13091296
}
1310-
1311-
return null;
1297+
invariant(
1298+
false,
1299+
'Unknown unit of work tag (%s). This error is likely caused by a bug in ' +
1300+
'React. Please file an issue.',
1301+
workInProgress.tag,
1302+
);
13121303
}
13131304

13141305
export {completeWork};

0 commit comments

Comments
 (0)