Warn if mounting into node with dirty rendered markup
Andreas Svensson committed
Jul 22, 2014 at 18:34 UTC
c460ad660b06e2cb602620353f11b642a368ebb2
3 files changed
+44
-2
src/browser/server/__tests__/ReactServerRendering-test.js
+2
-2
@@ -206,11 +206,11 @@ describe('ReactServerRendering', function() {
206
<TestComponent name="x" />
207
);
208
ExecutionEnvironment.canUseDOM = true;
209
- element.innerHTML = lastMarkup + ' __sentinel__';
209
+ element.innerHTML = lastMarkup;
210
211
React.render(<TestComponent name="x" />, element);
212
expect(mountCount).toEqual(3);
213
- expect(element.innerHTML.indexOf('__sentinel__') > -1).toBe(true);
213
+ expect(element.innerHTML).toBe(lastMarkup);
214
React.unmountComponentAtNode(element);
215
expect(element.innerHTML).toEqual('');
216
src/browser/ui/ReactMount.js
+18
@@ -468,6 +468,24 @@ var ReactMount = {
468
var containerHasReactMarkup =
469
reactRootElement && ReactMount.isRenderedByReact(reactRootElement);
470
471
+ if (__DEV__) {
472
+ if (!containerHasReactMarkup || reactRootElement.nextSibling) {
473
+ var rootElementSibling = reactRootElement;
474
+ while (rootElementSibling) {
475
+ if (ReactMount.isRenderedByReact(rootElementSibling)) {
476
+ console.warn(
477
+ 'render(): Target node has markup rendered by React, but there ' +
478
+ 'are unrelated nodes as well. This is most commonly caused by ' +
479
+ 'white-space inserted around server-rendered markup.'
480
+ );
481
+ break;
482
+ }
483
+
484
+ rootElementSibling = rootElementSibling.nextSibling;
485
+ }
486
+ }
487
+ }
488
+
489
var shouldReuseMarkup = containerHasReactMarkup && !prevComponent;
490
491
var component = ReactMount._renderNewRootComponent(
src/browser/ui/__tests__/ReactMount-test.js
+24
@@ -120,4 +120,28 @@ describe('ReactMount', function() {
120
121
expect(instance1 === instance2).toBe(true);
122
});
123
+
124
+ it('should warn if mounting into dirty rendered markup', function() {
125
+ var container = document.createElement('container');
126
+ container.innerHTML = React.renderToString(<div />) + ' ';
127
+
128
+ console.warn = mocks.getMockFunction();
129
+ ReactMount.render(<div />, container);
130
+ expect(console.warn.mock.calls.length).toBe(1);
131
+
132
+ container.innerHTML = ' ' + React.renderToString(<div />);
133
+
134
+ console.warn = mocks.getMockFunction();
135
+ ReactMount.render(<div />, container);
136
+ expect(console.warn.mock.calls.length).toBe(1);
137
+ });
138
+
139
+ it('should not warn if mounting into non-empty node', function() {
140
+ var container = document.createElement('container');
141
+ container.innerHTML = '<div></div>';
142
+
143
+ console.warn = mocks.getMockFunction();
144
+ ReactMount.render(<div />, container);
145
+ expect(console.warn.mock.calls.length).toBe(0);
146
+ });
147
});