@samitouri / QOS-React / commits / 4c270375e9

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

Sebastian Markbåge committed Dec 18, 2019 at 15:53 UTC 4c270375e931b133261495e3aa3f34407c5f79d8
3 files changed +76 -93
packages/react-reconciler/src/ReactFiberBeginWork.js
+23 -26
@@ -1075,7 +1075,7 @@ function mountLazyComponent(
1075 resolvedProps,
1076 renderExpirationTime,
1077 );
1078 - break;
1078 + return child;
1079 }
1080 case ClassComponent: {
1081 if (__DEV__) {
@@ -1090,7 +1090,7 @@ function mountLazyComponent(
1090 resolvedProps,
1091 renderExpirationTime,
1092 );
1093 - break;
1093 + return child;
1094 }
1095 case ForwardRef: {
1096 if (__DEV__) {
@@ -1105,7 +1105,7 @@ function mountLazyComponent(
1105 resolvedProps,
1106 renderExpirationTime,
1107 );
1108 - break;
1108 + return child;
1109 }
1110 case MemoComponent: {
1111 if (__DEV__) {
@@ -1130,32 +1130,29 @@ function mountLazyComponent(
1130 updateExpirationTime,
1131 renderExpirationTime,
1132 );
1133 - break;
1133 + return child;
1134 }
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?';
1144 }
1145 }
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 + );
1156 }
1157
1158 function mountIncompleteClassComponent(
packages/react-reconciler/src/ReactFiberCommitWork.js
+27 -32
@@ -320,14 +320,12 @@ function commitBeforeMutationLifeCycles(
320 case IncompleteClassComponent:
321 // Nothing to do for these component types
322 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 - }
323 }
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 }
330
331 function commitHookEffectList(
@@ -420,7 +418,7 @@ function commitLifeCycles(
418 case ForwardRef:
419 case SimpleMemoComponent: {
420 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
423 - break;
421 + return;
422 }
423 case ClassComponent: {
424 const instance = finishedWork.stateNode;
@@ -629,14 +627,12 @@ function commitLifeCycles(
627 case FundamentalComponent:
628 case ScopeComponent:
629 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 - }
630 }
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 + );
636 }
637
638 function hideOrUnhideAllChildren(finishedWork, isHidden) {
@@ -785,7 +781,7 @@ function commitUnmount(
781 });
782 }
783 }
788 - break;
784 + return;
785 }
786 case ClassComponent: {
787 safelyDetachRef(current);
@@ -843,6 +839,7 @@ function commitUnmount(
839 if (enableScopeAPI) {
840 safelyDetachRef(current);
841 }
842 + return;
843 }
844 }
845 }
@@ -943,14 +940,12 @@ function commitContainer(finishedWork: Fiber) {
940 replaceContainerChildren(containerInfo, pendingChildren);
941 return;
942 }
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 - }
943 }
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 + );
949 }
950
951 function getHostParentFiber(fiber: Fiber): Fiber {
@@ -1408,8 +1403,9 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
1403 if (enableFundamentalAPI) {
1404 const fundamentalInstance = finishedWork.stateNode;
1405 updateFundamentalComponent(fundamentalInstance);
1406 + return;
1407 }
1412 - return;
1408 + break;
1409 }
1410 case ScopeComponent: {
1411 if (enableScopeAPI) {
@@ -1424,17 +1420,16 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
1420 updateDeprecatedEventListeners(nextListeners, finishedWork, null);
1421 }
1422 }
1423 + return;
1424 }
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;
1426 }
1427 }
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 + );
1433 }
1434
1435 function commitSuspenseComponent(finishedWork: Fiber) {
packages/react-reconciler/src/ReactFiberCompleteWork.js
+26 -35
@@ -638,18 +638,22 @@ function completeWork(
638
639 switch (workInProgress.tag) {
640 case IndeterminateComponent:
641 - break;
641 case LazyComponent:
643 - break;
642 case SimpleMemoComponent:
643 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;
651 case ClassComponent: {
652 const Component = workInProgress.type;
653 if (isLegacyContextProvider(Component)) {
654 popLegacyContext(workInProgress);
655 }
652 - break;
656 + return null;
657 }
658 case HostRoot: {
659 popHostContainer(workInProgress);
@@ -670,7 +674,7 @@ function completeWork(
674 }
675 }
676 updateHostContainer(workInProgress);
673 - break;
677 + return null;
678 }
679 case HostComponent: {
680 popHostContext(workInProgress);
@@ -704,7 +708,7 @@ function completeWork(
708 'caused by a bug in React. Please file an issue.',
709 );
710 // This can happen when we abort work.
707 - break;
711 + return null;
712 }
713
714 const currentHostContext = getHostContext();
@@ -783,7 +787,7 @@ function completeWork(
787 markRef(workInProgress);
788 }
789 }
786 - break;
790 + return null;
791 }
792 case HostText: {
793 let newText = newProps;
@@ -817,10 +821,8 @@ function completeWork(
821 );
822 }
823 }
820 - break;
824 + return null;
825 }
822 - case ForwardRef:
823 - break;
826 case SuspenseComponent: {
827 popSuspenseContext(workInProgress);
828 const nextState: null | SuspenseState = workInProgress.memoizedState;
@@ -961,26 +963,16 @@ function completeWork(
963 // Always notify the callback
964 workInProgress.effectTag |= Update;
965 }
964 - break;
966 + return null;
967 }
966 - case Fragment:
967 - break;
968 - case Mode:
969 - break;
970 - case Profiler:
971 - break;
968 case HostPortal:
969 popHostContainer(workInProgress);
970 updateHostContainer(workInProgress);
975 - break;
971 + return null;
972 case ContextProvider:
973 // Pop provider fiber
974 popProvider(workInProgress);
979 - break;
980 - case ContextConsumer:
981 - break;
982 - case MemoComponent:
983 - break;
975 + return null;
976 case IncompleteClassComponent: {
977 // Same as class component case. I put it down here so that the tags are
978 // sequential to ensure this switch is compiled to a jump table.
@@ -988,7 +980,7 @@ function completeWork(
980 if (isLegacyContextProvider(Component)) {
981 popLegacyContext(workInProgress);
982 }
991 - break;
983 + return null;
984 }
985 case SuspenseListComponent: {
986 popSuspenseContext(workInProgress);
@@ -999,7 +991,7 @@ function completeWork(
991 if (renderState === null) {
992 // We're running in the default, "independent" mode. We don't do anything
993 // in this mode.
1002 - break;
994 + return null;
995 }
996
997 let didSuspendAlready =
@@ -1198,7 +1190,7 @@ function completeWork(
1190 // Do a pass over the next row.
1191 return next;
1192 }
1201 - break;
1193 + return null;
1194 }
1195 case FundamentalComponent: {
1196 if (enableFundamentalAPI) {
@@ -1248,6 +1240,7 @@ function completeWork(
1240 markUpdate(workInProgress);
1241 }
1242 }
1243 + return null;
1244 }
1245 break;
1246 }
@@ -1296,19 +1289,17 @@ function completeWork(
1289 markRef(workInProgress);
1290 }
1291 }
1292 + return null;
1293 }
1294 break;
1295 }
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 - );
1296 }
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 + );
1303 }
1304
1305 export {completeWork};