diff --git a/src/browser/server/__tests__/ReactServerRendering-test.js b/src/browser/server/__tests__/ReactServerRendering-test.js index 50b03234af..edea82af32 100644 --- a/src/browser/server/__tests__/ReactServerRendering-test.js +++ b/src/browser/server/__tests__/ReactServerRendering-test.js @@ -206,11 +206,11 @@ describe('ReactServerRendering', function() { ); ExecutionEnvironment.canUseDOM = true; - element.innerHTML = lastMarkup + ' __sentinel__'; + element.innerHTML = lastMarkup; React.render(, element); expect(mountCount).toEqual(3); - expect(element.innerHTML.indexOf('__sentinel__') > -1).toBe(true); + expect(element.innerHTML).toBe(lastMarkup); React.unmountComponentAtNode(element); expect(element.innerHTML).toEqual(''); diff --git a/src/browser/ui/ReactMount.js b/src/browser/ui/ReactMount.js index 7950ff1019..fdfda0cb68 100644 --- a/src/browser/ui/ReactMount.js +++ b/src/browser/ui/ReactMount.js @@ -468,6 +468,24 @@ var ReactMount = { var containerHasReactMarkup = reactRootElement && ReactMount.isRenderedByReact(reactRootElement); + if (__DEV__) { + if (!containerHasReactMarkup || reactRootElement.nextSibling) { + var rootElementSibling = reactRootElement; + while (rootElementSibling) { + if (ReactMount.isRenderedByReact(rootElementSibling)) { + console.warn( + 'render(): Target node has markup rendered by React, but there ' + + 'are unrelated nodes as well. This is most commonly caused by ' + + 'white-space inserted around server-rendered markup.' + ); + break; + } + + rootElementSibling = rootElementSibling.nextSibling; + } + } + } + var shouldReuseMarkup = containerHasReactMarkup && !prevComponent; var component = ReactMount._renderNewRootComponent( diff --git a/src/browser/ui/__tests__/ReactMount-test.js b/src/browser/ui/__tests__/ReactMount-test.js index 8634524178..a23a280aef 100644 --- a/src/browser/ui/__tests__/ReactMount-test.js +++ b/src/browser/ui/__tests__/ReactMount-test.js @@ -120,4 +120,28 @@ describe('ReactMount', function() { expect(instance1 === instance2).toBe(true); }); + + it('should warn if mounting into dirty rendered markup', function() { + var container = document.createElement('container'); + container.innerHTML = React.renderToString(
) + ' '; + + console.warn = mocks.getMockFunction(); + ReactMount.render(
, container); + expect(console.warn.mock.calls.length).toBe(1); + + container.innerHTML = ' ' + React.renderToString(
); + + console.warn = mocks.getMockFunction(); + ReactMount.render(
, container); + expect(console.warn.mock.calls.length).toBe(1); + }); + + it('should not warn if mounting into non-empty node', function() { + var container = document.createElement('container'); + container.innerHTML = '
'; + + console.warn = mocks.getMockFunction(); + ReactMount.render(
, container); + expect(console.warn.mock.calls.length).toBe(0); + }); });