Disallow Fiber-only render return types when feature flag is on
Except for portals, which we use in some places.
Andrew Clark committed
Jan 11, 2017 at 17:49 UTC
86280187d7b9a0708e9268d4a17aa7c32f414da0
2 files changed
+62
src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
+28
@@ -1002,5 +1002,33 @@ describe('ReactDOMFiber', () => {
1002
container
1003
);
1004
});
1005
+
1006
+ describe('disableNewFiberFeatures', () => {
1007
+ var ReactFeatureFlags = require('ReactFeatureFlags');
1008
+
1009
+ beforeEach(() => {
1010
+ ReactFeatureFlags.disableNewFiberFeatures = true;
1011
+ });
1012
+
1013
+ afterEach(() => {
1014
+ ReactFeatureFlags.disableNewFiberFeatures = false;
1015
+ });
1016
+
1017
+ it('throws if something other than false, null, or an element is returned from render', () => {
1018
+ function Render(props) {
1019
+ return props.children;
1020
+ }
1021
+
1022
+ const message = (
1023
+ 'Warning: Render.render(): A valid React element (or null) must ' +
1024
+ 'be returned. You may have returned undefined, an array or some ' +
1025
+ 'other invalid object.'
1026
+ );
1027
+
1028
+ expect(() => ReactDOM.render(<Render>Hi</Render>, container)).toThrow(message);
1029
+ expect(() => ReactDOM.render(<Render>{999}</Render>, container)).toThrow(message);
1030
+ expect(() => ReactDOM.render(<Render>[<div />]</Render>, container)).toThrow(message);
1031
+ });
1032
+ });
1033
}
1034
});
src/renderers/shared/fiber/ReactChildFiber.js
+34
@@ -36,6 +36,7 @@ var ReactTypeOfWork = require('ReactTypeOfWork');
36
var emptyObject = require('emptyObject');
37
var getIteratorFn = require('getIteratorFn');
38
var invariant = require('invariant');
39
+var ReactFeatureFlags = require('ReactFeatureFlags');
40
41
if (__DEV__) {
42
var { getCurrentFiberStackAddendum } = require('ReactDebugCurrentFiber');
@@ -1100,6 +1101,39 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1101
// not as a fragment. Nested arrays on the other hand will be treated as
1102
// fragment nodes. Recursion happens at the normal flow.
1103
1104
+ if (ReactFeatureFlags.disableNewFiberFeatures) {
1105
+ // Support only the subset of return types that Stack supports. Treat
1106
+ // everything else as empty, but log a warning.
1107
+ if (typeof newChild === 'object' && newChild !== null) {
1108
+ switch (newChild.$$typeof) {
1109
+ case REACT_ELEMENT_TYPE:
1110
+ return placeSingleChild(reconcileSingleElement(
1111
+ returnFiber,
1112
+ currentFirstChild,
1113
+ newChild,
1114
+ priority
1115
+ ));
1116
+
1117
+ case REACT_PORTAL_TYPE:
1118
+ return placeSingleChild(reconcileSinglePortal(
1119
+ returnFiber,
1120
+ currentFirstChild,
1121
+ newChild,
1122
+ priority
1123
+ ));
1124
+ }
1125
+ }
1126
+
1127
+ const Component = returnFiber.type;
1128
+ invariant(
1129
+ newChild === null || newChild === false,
1130
+ '%s.render(): A valid React element (or null) must be returned. You ' +
1131
+ 'may have returned undefined, an array or some other invalid object.',
1132
+ Component.displayName || Component.name || 'Component'
1133
+ );
1134
+ return deleteRemainingChildren(returnFiber, currentFirstChild);
1135
+ }
1136
+
1137
if (typeof newChild === 'string' || typeof newChild === 'number') {
1138
return placeSingleChild(reconcileSingleTextNode(
1139
returnFiber,