@samitouri / QOS-React / commits / ba1d3829bc

Use multiple checks instead of forking the entire function

Easier to follow this way, and less chance the two paths will get out of sync.

Andrew Clark committed Jan 25, 2017 at 11:52 UTC ba1d3829bcb19b5b015a212d4379bdaed5c48dfc
1 file changed +63 -88
src/renderers/shared/fiber/ReactChildFiber.js
+63 -88
@@ -64,7 +64,6 @@ const {
64 FunctionalComponent,
65 ClassComponent,
66 HostText,
67 - HostRoot,
67 HostPortal,
68 CoroutineComponent,
69 YieldComponent,
@@ -1103,10 +1102,13 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1102 // not as a fragment. Nested arrays on the other hand will be treated as
1103 // fragment nodes. Recursion happens at the normal flow.
1104
1106 - if (ReactFeatureFlags.disableNewFiberFeatures) {
1105 + const disableNewFiberFeatures = ReactFeatureFlags.disableNewFiberFeatures;
1106 +
1107 + // Handle object types
1108 + if (typeof newChild === 'object' && newChild !== null) {
1109 // Support only the subset of return types that Stack supports. Treat
1110 // everything else as empty, but log a warning.
1109 - if (typeof newChild === 'object' && newChild !== null) {
1111 + if (disableNewFiberFeatures) {
1112 switch (newChild.$$typeof) {
1113 case REACT_ELEMENT_TYPE:
1114 return placeSingleChild(reconcileSingleElement(
@@ -1116,6 +1118,40 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
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 {
1130 + switch (newChild.$$typeof) {
1131 + case REACT_ELEMENT_TYPE:
1132 + return placeSingleChild(reconcileSingleElement(
1133 + returnFiber,
1134 + currentFirstChild,
1135 + newChild,
1136 + priority
1137 + ));
1138 +
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 +
1155 case REACT_PORTAL_TYPE:
1156 return placeSingleChild(reconcileSinglePortal(
1157 returnFiber,
@@ -1125,7 +1161,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1161 ));
1162 }
1163 }
1164 + }
1165
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__) {
@@ -1152,35 +1192,6 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1192 );
1193 }
1194 }
1155 -
1156 - if (typeof newChild === 'string' || typeof newChild === 'number') {
1157 - return placeSingleChild(reconcileSingleTextNode(
1158 - returnFiber,
1159 - currentFirstChild,
1160 - '' + newChild,
1161 - priority
1162 - ));
1163 - }
1164 -
1165 - if (isArray(newChild)) {
1166 - return reconcileChildrenArray(
1167 - returnFiber,
1168 - currentFirstChild,
1169 - newChild,
1170 - priority
1171 - );
1172 - }
1173 -
1174 - if (getIteratorFn(newChild)) {
1175 - return reconcileChildrenIterator(
1176 - returnFiber,
1177 - currentFirstChild,
1178 - newChild,
1179 - priority
1180 - );
1181 - }
1182 -
1183 - return deleteRemainingChildren(returnFiber, currentFirstChild);
1195 }
1196
1197 if (typeof newChild === 'string' || typeof newChild === 'number') {
@@ -1192,69 +1203,33 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1203 ));
1204 }
1205
1195 - if (typeof newChild === 'object' && newChild !== null) {
1196 - switch (newChild.$$typeof) {
1197 - case REACT_ELEMENT_TYPE:
1198 - return placeSingleChild(reconcileSingleElement(
1199 - returnFiber,
1200 - currentFirstChild,
1201 - newChild,
1202 - priority
1203 - ));
1204 -
1205 - case REACT_COROUTINE_TYPE:
1206 - return placeSingleChild(reconcileSingleCoroutine(
1207 - returnFiber,
1208 - currentFirstChild,
1209 - newChild,
1210 - priority
1211 - ));
1212 -
1213 - case REACT_YIELD_TYPE:
1214 - return placeSingleChild(reconcileSingleYield(
1215 - returnFiber,
1216 - currentFirstChild,
1217 - newChild,
1218 - priority
1219 - ));
1220 -
1221 - case REACT_PORTAL_TYPE:
1222 - return placeSingleChild(reconcileSinglePortal(
1223 - returnFiber,
1224 - currentFirstChild,
1225 - newChild,
1226 - priority
1227 - ));
1228 - }
1229 -
1230 - if (isArray(newChild)) {
1231 - return reconcileChildrenArray(
1232 - returnFiber,
1233 - currentFirstChild,
1234 - newChild,
1235 - priority
1236 - );
1237 - }
1206 + if (isArray(newChild)) {
1207 + return reconcileChildrenArray(
1208 + returnFiber,
1209 + currentFirstChild,
1210 + newChild,
1211 + priority
1212 + );
1213 + }
1214
1239 - if (getIteratorFn(newChild)) {
1240 - return reconcileChildrenIterator(
1241 - returnFiber,
1242 - currentFirstChild,
1243 - newChild,
1244 - priority
1245 - );
1246 - }
1215 + if (getIteratorFn(newChild)) {
1216 + return reconcileChildrenIterator(
1217 + returnFiber,
1218 + currentFirstChild,
1219 + newChild,
1220 + priority
1221 + );
1222 }
1223
1249 - 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.
1228 switch (returnFiber.tag) {
1251 - case HostRoot:
1252 - // TODO: Top-level render
1253 - break;
1229 case ClassComponent: {
1230 if (__DEV__) {
1231 const instance = returnFiber.stateNode;
1257 - if (instance.render._isMockFunction && typeof newChild === 'undefined') {
1232 + if (instance.render._isMockFunction) {
1233 // We allow auto-mocks to proceed as if they're returning null.
1234 break;
1235 }