Warn when nesting 15 subtree inside 16 (#10434)
Ben Alpert committed
Aug 13, 2017 at 16:03 UTC
9921e572722c0fa9d3cda65317f6de60f5d0919f
3 files changed
+53
-4
src/renderers/dom/shared/__tests__/renderSubtreeIntoContainer-test.js
+24
@@ -14,6 +14,7 @@
14
var React = require('react');
15
var PropTypes = require('prop-types');
16
var ReactDOM = require('react-dom');
17
+var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
18
var ReactTestUtils = require('react-dom/test-utils');
19
var renderSubtreeIntoContainer = require('react-dom')
20
.unstable_renderSubtreeIntoContainer;
@@ -299,4 +300,27 @@ describe('renderSubtreeIntoContainer', () => {
300
ReactDOM.render(<Parent value="foo" />, container);
301
expect(portal2.textContent).toBe('foo');
302
});
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
+ }
326
});
src/renderers/shared/fiber/ReactFiberClassComponent.js
+25
@@ -40,6 +40,7 @@ var getComponentName = require('getComponentName');
40
var shallowEqual = require('fbjs/lib/shallowEqual');
41
var invariant = require('fbjs/lib/invariant');
42
43
+const fakeInternalInstance = {};
44
const isArray = Array.isArray;
45
46
if (__DEV__) {
@@ -54,6 +55,27 @@ if (__DEV__) {
55
callback,
56
);
57
};
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);
79
}
80
81
module.exports = function(
@@ -283,6 +305,9 @@ module.exports = function(
305
workInProgress.stateNode = instance;
306
// The instance needs access to the fiber so that it can schedule updates
307
ReactInstanceMap.set(instance, workInProgress);
308
+ if (__DEV__) {
309
+ instance._reactInternalInstance = fakeInternalInstance;
310
+ }
311
}
312
313
function constructClassInstance(workInProgress: Fiber, props: any): any {
src/renderers/shared/shared/ReactInstanceMap.js
+4
-4
@@ -26,19 +26,19 @@ var ReactInstanceMap = {
26
* supported we can rename it.
27
*/
28
remove: function(key) {
29
- key._reactInternalInstance = undefined;
29
+ key._reactInternalFiber = undefined;
30
},
31
32
get: function(key) {
33
- return key._reactInternalInstance;
33
+ return key._reactInternalFiber;
34
},
35
36
has: function(key) {
37
- return key._reactInternalInstance !== undefined;
37
+ return key._reactInternalFiber !== undefined;
38
},
39
40
set: function(key, value) {
41
- key._reactInternalInstance = value;
41
+ key._reactInternalFiber = value;
42
},
43
};
44