diff --git a/packages/react-test-renderer/src/ReactTestHostConfig.js b/packages/react-test-renderer/src/ReactTestHostConfig.js index e42a8c4baebe7..d2312251f8a8e 100644 --- a/packages/react-test-renderer/src/ReactTestHostConfig.js +++ b/packages/react-test-renderer/src/ReactTestHostConfig.js @@ -7,6 +7,7 @@ * @flow */ +import warning from 'shared/warning'; import * as TestRendererScheduling from './ReactTestRendererScheduling'; export type Type = string; @@ -62,6 +63,15 @@ export function appendChild( parentInstance: Instance | Container, child: Instance | TextInstance, ): void { + if (__DEV__) { + warning( + Array.isArray(parentInstance.children), + 'An invalid container has been provided. ' + + 'This may indicate that another render is being used in addition to the test renderer. ' + + '(For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) ' + + 'This is not supported.', + ); + } const index = parentInstance.children.indexOf(child); if (index !== -1) { parentInstance.children.splice(index, 1); diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js new file mode 100644 index 0000000000000..5220d2fd0c2bf --- /dev/null +++ b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @emails react-core + */ + +'use strict'; + +const ReactDOM = require('react-dom'); + +// Isolate test renderer. +jest.resetModules(); +const ReactTestRenderer = require('react-test-renderer'); + +describe('ReactTestRenderer', () => { + it('should warn if used to render a ReactDOM portal', () => { + const container = document.createElement('div'); + expect(() => { + expect(() => { + ReactTestRenderer.create(ReactDOM.createPortal('foo', container)); + }).toThrow(); + }).toWarnDev('An invalid container has been provided.', { + withoutStack: true, + }); + }); +});