Disallow Fiber-only render return types when feature flag is on

Except for portals, which we use in some places.
This commit is contained in:
Andrew Clark
2017-01-11 18:01:36 -08:00
parent bf117f82e1
commit 86280187d7
2 changed files with 62 additions and 0 deletions
@@ -1002,5 +1002,33 @@ describe('ReactDOMFiber', () => {
container
);
});
describe('disableNewFiberFeatures', () => {
var ReactFeatureFlags = require('ReactFeatureFlags');
beforeEach(() => {
ReactFeatureFlags.disableNewFiberFeatures = true;
});
afterEach(() => {
ReactFeatureFlags.disableNewFiberFeatures = false;
});
it('throws if something other than false, null, or an element is returned from render', () => {
function Render(props) {
return props.children;
}
const message = (
'Warning: Render.render(): A valid React element (or null) must ' +
'be returned. You may have returned undefined, an array or some ' +
'other invalid object.'
);
expect(() => ReactDOM.render(<Render>Hi</Render>, container)).toThrow(message);
expect(() => ReactDOM.render(<Render>{999}</Render>, container)).toThrow(message);
expect(() => ReactDOM.render(<Render>[<div />]</Render>, container)).toThrow(message);
});
});
}
});
@@ -36,6 +36,7 @@ var ReactTypeOfWork = require('ReactTypeOfWork');
var emptyObject = require('emptyObject');
var getIteratorFn = require('getIteratorFn');
var invariant = require('invariant');
var ReactFeatureFlags = require('ReactFeatureFlags');
if (__DEV__) {
var { getCurrentFiberStackAddendum } = require('ReactDebugCurrentFiber');
@@ -1100,6 +1101,39 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
// not as a fragment. Nested arrays on the other hand will be treated as
// fragment nodes. Recursion happens at the normal flow.
if (ReactFeatureFlags.disableNewFiberFeatures) {
// Support only the subset of return types that Stack supports. Treat
// everything else as empty, but log a warning.
if (typeof newChild === 'object' && newChild !== null) {
switch (newChild.$$typeof) {
case REACT_ELEMENT_TYPE:
return placeSingleChild(reconcileSingleElement(
returnFiber,
currentFirstChild,
newChild,
priority
));
case REACT_PORTAL_TYPE:
return placeSingleChild(reconcileSinglePortal(
returnFiber,
currentFirstChild,
newChild,
priority
));
}
}
const Component = returnFiber.type;
invariant(
newChild === null || newChild === false,
'%s.render(): A valid React element (or null) must be returned. You ' +
'may have returned undefined, an array or some other invalid object.',
Component.displayName || Component.name || 'Component'
);
return deleteRemainingChildren(returnFiber, currentFirstChild);
}
if (typeof newChild === 'string' || typeof newChild === 'number') {
return placeSingleChild(reconcileSingleTextNode(
returnFiber,