diff --git a/src/renderers/dom/shared/__tests__/renderSubtreeIntoContainer-test.js b/src/renderers/dom/shared/__tests__/renderSubtreeIntoContainer-test.js
index 43ac5cb5b2b5..cca63bffa77f 100644
--- a/src/renderers/dom/shared/__tests__/renderSubtreeIntoContainer-test.js
+++ b/src/renderers/dom/shared/__tests__/renderSubtreeIntoContainer-test.js
@@ -14,6 +14,7 @@
var React = require('react');
var PropTypes = require('prop-types');
var ReactDOM = require('react-dom');
+var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
var ReactTestUtils = require('react-dom/test-utils');
var renderSubtreeIntoContainer = require('react-dom')
.unstable_renderSubtreeIntoContainer;
@@ -299,4 +300,27 @@ describe('renderSubtreeIntoContainer', () => {
ReactDOM.render(, container);
expect(portal2.textContent).toBe('foo');
});
+
+ if (ReactDOMFeatureFlags.useFiber) {
+ it('fails gracefully when mixing React 15 and 16', () => {
+ class C extends React.Component {
+ render() {
+ return
;
+ }
+ }
+ const c = ReactDOM.render(, document.createElement('div'));
+ // React 15 calls this:
+ // https://github.com/facebook/react/blob/77b71fc3c4/src/renderers/dom/client/ReactMount.js#L478-L479
+ expect(() => {
+ c._reactInternalInstance._processChildContext({});
+ }).toThrow(
+ '_processChildContext is not available in React 16+. This likely ' +
+ 'means you have multiple copies of React and are attempting to nest ' +
+ 'a React 15 tree inside a React 16 tree using ' +
+ "unstable_renderSubtreeIntoContainer, which isn't supported. Try to " +
+ 'make sure you have only one copy of React (and ideally, switch to ' +
+ 'ReactDOM.unstable_createPortal).',
+ );
+ });
+ }
});
diff --git a/src/renderers/shared/fiber/ReactFiberClassComponent.js b/src/renderers/shared/fiber/ReactFiberClassComponent.js
index a6cc6880020a..e726cfd56928 100644
--- a/src/renderers/shared/fiber/ReactFiberClassComponent.js
+++ b/src/renderers/shared/fiber/ReactFiberClassComponent.js
@@ -40,6 +40,7 @@ var getComponentName = require('getComponentName');
var shallowEqual = require('fbjs/lib/shallowEqual');
var invariant = require('fbjs/lib/invariant');
+const fakeInternalInstance = {};
const isArray = Array.isArray;
if (__DEV__) {
@@ -54,6 +55,27 @@ if (__DEV__) {
callback,
);
};
+
+ // This is so gross but it's at least non-critical and can be removed if
+ // it causes problems. This is meant to give a nicer error message for
+ // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
+ // ...)) which otherwise throws a "_processChildContext is not a function"
+ // exception.
+ Object.defineProperty(fakeInternalInstance, '_processChildContext', {
+ enumerable: false,
+ value: function() {
+ invariant(
+ false,
+ '_processChildContext is not available in React 16+. This likely ' +
+ 'means you have multiple copies of React and are attempting to nest ' +
+ 'a React 15 tree inside a React 16 tree using ' +
+ "unstable_renderSubtreeIntoContainer, which isn't supported. Try " +
+ 'to make sure you have only one copy of React (and ideally, switch ' +
+ 'to ReactDOM.unstable_createPortal).',
+ );
+ },
+ });
+ Object.freeze(fakeInternalInstance);
}
module.exports = function(
@@ -283,6 +305,9 @@ module.exports = function(
workInProgress.stateNode = instance;
// The instance needs access to the fiber so that it can schedule updates
ReactInstanceMap.set(instance, workInProgress);
+ if (__DEV__) {
+ instance._reactInternalInstance = fakeInternalInstance;
+ }
}
function constructClassInstance(workInProgress: Fiber, props: any): any {
diff --git a/src/renderers/shared/shared/ReactInstanceMap.js b/src/renderers/shared/shared/ReactInstanceMap.js
index 495c82c311b6..c26c3c959a16 100644
--- a/src/renderers/shared/shared/ReactInstanceMap.js
+++ b/src/renderers/shared/shared/ReactInstanceMap.js
@@ -26,19 +26,19 @@ var ReactInstanceMap = {
* supported we can rename it.
*/
remove: function(key) {
- key._reactInternalInstance = undefined;
+ key._reactInternalFiber = undefined;
},
get: function(key) {
- return key._reactInternalInstance;
+ return key._reactInternalFiber;
},
has: function(key) {
- return key._reactInternalInstance !== undefined;
+ return key._reactInternalFiber !== undefined;
},
set: function(key, value) {
- key._reactInternalInstance = value;
+ key._reactInternalFiber = value;
},
};