Skip to content

Commit 9921e57

Browse files
authored
Warn when nesting 15 subtree inside 16 (#10434)
1 parent 5ff5700 commit 9921e57

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

src/renderers/dom/shared/__tests__/renderSubtreeIntoContainer-test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
var React = require('react');
1515
var PropTypes = require('prop-types');
1616
var ReactDOM = require('react-dom');
17+
var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
1718
var ReactTestUtils = require('react-dom/test-utils');
1819
var renderSubtreeIntoContainer = require('react-dom')
1920
.unstable_renderSubtreeIntoContainer;
@@ -299,4 +300,27 @@ describe('renderSubtreeIntoContainer', () => {
299300
ReactDOM.render(<Parent value="foo" />, container);
300301
expect(portal2.textContent).toBe('foo');
301302
});
303+
304+
if (ReactDOMFeatureFlags.useFiber) {
305+
it('fails gracefully when mixing React 15 and 16', () => {
306+
class C extends React.Component {
307+
render() {
308+
return <div />;
309+
}
310+
}
311+
const c = ReactDOM.render(<C />, document.createElement('div'));
312+
// React 15 calls this:
313+
// https://github.com/facebook/react/blob/77b71fc3c4/src/renderers/dom/client/ReactMount.js#L478-L479
314+
expect(() => {
315+
c._reactInternalInstance._processChildContext({});
316+
}).toThrow(
317+
'_processChildContext is not available in React 16+. This likely ' +
318+
'means you have multiple copies of React and are attempting to nest ' +
319+
'a React 15 tree inside a React 16 tree using ' +
320+
"unstable_renderSubtreeIntoContainer, which isn't supported. Try to " +
321+
'make sure you have only one copy of React (and ideally, switch to ' +
322+
'ReactDOM.unstable_createPortal).',
323+
);
324+
});
325+
}
302326
});

src/renderers/shared/fiber/ReactFiberClassComponent.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ var getComponentName = require('getComponentName');
4040
var shallowEqual = require('fbjs/lib/shallowEqual');
4141
var invariant = require('fbjs/lib/invariant');
4242

43+
const fakeInternalInstance = {};
4344
const isArray = Array.isArray;
4445

4546
if (__DEV__) {
@@ -54,6 +55,27 @@ if (__DEV__) {
5455
callback,
5556
);
5657
};
58+
59+
// This is so gross but it's at least non-critical and can be removed if
60+
// it causes problems. This is meant to give a nicer error message for
61+
// ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
62+
// ...)) which otherwise throws a "_processChildContext is not a function"
63+
// exception.
64+
Object.defineProperty(fakeInternalInstance, '_processChildContext', {
65+
enumerable: false,
66+
value: function() {
67+
invariant(
68+
false,
69+
'_processChildContext is not available in React 16+. This likely ' +
70+
'means you have multiple copies of React and are attempting to nest ' +
71+
'a React 15 tree inside a React 16 tree using ' +
72+
"unstable_renderSubtreeIntoContainer, which isn't supported. Try " +
73+
'to make sure you have only one copy of React (and ideally, switch ' +
74+
'to ReactDOM.unstable_createPortal).',
75+
);
76+
},
77+
});
78+
Object.freeze(fakeInternalInstance);
5779
}
5880

5981
module.exports = function(
@@ -283,6 +305,9 @@ module.exports = function(
283305
workInProgress.stateNode = instance;
284306
// The instance needs access to the fiber so that it can schedule updates
285307
ReactInstanceMap.set(instance, workInProgress);
308+
if (__DEV__) {
309+
instance._reactInternalInstance = fakeInternalInstance;
310+
}
286311
}
287312

288313
function constructClassInstance(workInProgress: Fiber, props: any): any {

src/renderers/shared/shared/ReactInstanceMap.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,19 @@ var ReactInstanceMap = {
2626
* supported we can rename it.
2727
*/
2828
remove: function(key) {
29-
key._reactInternalInstance = undefined;
29+
key._reactInternalFiber = undefined;
3030
},
3131

3232
get: function(key) {
33-
return key._reactInternalInstance;
33+
return key._reactInternalFiber;
3434
},
3535

3636
has: function(key) {
37-
return key._reactInternalInstance !== undefined;
37+
return key._reactInternalFiber !== undefined;
3838
},
3939

4040
set: function(key, value) {
41-
key._reactInternalInstance = value;
41+
key._reactInternalFiber = value;
4242
},
4343
};
4444

0 commit comments

Comments
 (0)