@samitouri / QOS-React / commits / c8adedc054

Warn if undefined is passed to top-level render

Moved the top-level check to ReactChildFiber like the other ones

Andrew Clark committed Jan 11, 2017 at 18:24 UTC c8adedc05499a403781668b82ea758c4eb36b374
2 files changed +32 -25
src/renderers/shared/fiber/ReactChildFiber.js
+32 -16
@@ -1126,24 +1126,40 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1126 }
1127 }
1128
1129 - const Component = returnFiber.type;
1130 - let validEmptyReturnType = newChild === null || newChild === false;
1131 -
1132 - if (__DEV__) {
1133 - if (!validEmptyReturnType &&
1134 - returnFiber.tag === ClassComponent &&
1135 - returnFiber.stateNode.render._isMockFunction) {
1136 - // We allow auto-mocks to proceed as if they're returning null.
1137 - validEmptyReturnType = true;
1129 + if (returnFiber.tag === HostRoot) {
1130 + // Top-level only accepts elements or portals
1131 + invariant(
1132 + false,
1133 + 'render(): Invalid component element.'
1134 + );
1135 + } else {
1136 + switch (returnFiber.tag) {
1137 + case ClassComponent: {
1138 + if (__DEV__) {
1139 + const instance = returnFiber.stateNode;
1140 + if (instance.render._isMockFunction) {
1141 + // We allow auto-mocks to proceed as if they're
1142 + // returning null.
1143 + break;
1144 + }
1145 + }
1146 + }
1147 + // Intentionally fall through to the next case, which handles both
1148 + // functions and classes
1149 + // eslint-disable-next-lined no-fallthrough
1150 + case FunctionalComponent: {
1151 + // Composites accept elements, portals, null, or false
1152 + const Component = returnFiber.type;
1153 + invariant(
1154 + newChild === null || newChild === false,
1155 + '%s.render(): A valid React element (or null) must be ' +
1156 + 'returned. You may have returned undefined, an array or some ' +
1157 + 'other invalid object.',
1158 + Component.displayName || Component.name || 'Component'
1159 + );
1160 + }
1161 }
1162 }
1140 -
1141 - invariant(
1142 - validEmptyReturnType,
1143 - '%s.render(): A valid React element (or null) must be returned. You ' +
1144 - 'may have returned undefined, an array or some other invalid object.',
1145 - Component.displayName || Component.name || 'Component'
1146 - );
1163 return deleteRemainingChildren(returnFiber, currentFirstChild);
1164 }
1165
src/renderers/shared/fiber/ReactFiberReconciler.js
-9
@@ -17,10 +17,6 @@ import type { FiberRoot } from 'ReactFiberRoot';
17 import type { PriorityLevel } from 'ReactPriorityLevel';
18 import type { ReactNodeList } from 'ReactTypes';
19
20 -var { isValidElement } = require('ReactElement');
21 -var invariant = require('invariant');
22 -var ReactFeatureFlags = require('ReactFeatureFlags');
23 -
20 var {
21 addTopLevelUpdate,
22 } = require('ReactFiberUpdateQueue');
@@ -138,11 +134,6 @@ module.exports = function<T, P, I, TI, PI, C, CX>(config : HostConfig<T, P, I, T
134 },
135
136 updateContainer(element : ReactNodeList, container : OpaqueNode, parentComponent : ?ReactComponent<any, any, any>, callback: ?Function) : void {
141 - invariant(
142 - !ReactFeatureFlags.disableNewFiberFeatures || isValidElement(element),
143 - 'render(): Invalid component element.'
144 - );
145 -
137 // TODO: If this is a nested container, this won't be the root.
138 const root : FiberRoot = (container.stateNode : any);
139 const current = root.current;