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);
+ });
});