From 86280187d7b9a0708e9268d4a17aa7c32f414da0 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 11 Jan 2017 17:49:26 -0800 Subject: [PATCH] Disallow Fiber-only render return types when feature flag is on Except for portals, which we use in some places. --- .../dom/fiber/__tests__/ReactDOMFiber-test.js | 28 +++++++++++++++ src/renderers/shared/fiber/ReactChildFiber.js | 34 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js b/src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js index 9abec3eedd..21131897a5 100644 --- a/src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js +++ b/src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js @@ -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(Hi, container)).toThrow(message); + expect(() => ReactDOM.render({999}, container)).toThrow(message); + expect(() => ReactDOM.render([
], container)).toThrow(message); + }); + }); } }); diff --git a/src/renderers/shared/fiber/ReactChildFiber.js b/src/renderers/shared/fiber/ReactChildFiber.js index 9302c2ed80..115134e6b9 100644 --- a/src/renderers/shared/fiber/ReactChildFiber.js +++ b/src/renderers/shared/fiber/ReactChildFiber.js @@ -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,