From e2f2c1a47a63b1d2040efde60b4847bb2273f0ab Mon Sep 17 00:00:00 2001 From: syranide Date: Sat, 31 Jan 2015 20:19:07 +0100 Subject: [PATCH] Never reuse dirty rendered markup when mounting --- src/browser/ui/ReactMount.js | 14 +++++---- src/browser/ui/__tests__/ReactMount-test.js | 33 +++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/browser/ui/ReactMount.js b/src/browser/ui/ReactMount.js index fdfda0cb68c..6cd529f1c72 100644 --- a/src/browser/ui/ReactMount.js +++ b/src/browser/ui/ReactMount.js @@ -465,18 +465,22 @@ var ReactMount = { } var reactRootElement = getReactRootElementInContainer(container); - var containerHasReactMarkup = - reactRootElement && ReactMount.isRenderedByReact(reactRootElement); + var containerHasReactMarkup = ( + reactRootElement && + !reactRootElement.nextSibling && + ReactMount.isRenderedByReact(reactRootElement) + ); if (__DEV__) { - if (!containerHasReactMarkup || reactRootElement.nextSibling) { + if (!prevComponent && reactRootElement && 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.' + 'are unrelated nodes as well. The markup rendered by React has ' + + 'not been reused. This is most commonly caused by white-space ' + + 'inserted around server-rendered markup.' ); break; } diff --git a/src/browser/ui/__tests__/ReactMount-test.js b/src/browser/ui/__tests__/ReactMount-test.js index a23a280aef6..cf10ee6ca5e 100644 --- a/src/browser/ui/__tests__/ReactMount-test.js +++ b/src/browser/ui/__tests__/ReactMount-test.js @@ -134,6 +134,12 @@ describe('ReactMount', function() { 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(0); }); it('should not warn if mounting into non-empty node', function() { @@ -144,4 +150,31 @@ describe('ReactMount', function() { ReactMount.render(
, container); expect(console.warn.mock.calls.length).toBe(0); }); + + it('should reuse if mounting into rendered markup', function() { + var container = document.createElement('container'); + container.innerHTML = React.renderToString(
); + + var renderedNode = container.firstChild; + ReactMount.render(
, container); + expect(container.firstChild).toBe(renderedNode); + }); + + it('should not reuse if mounting into dirty rendered markup', function() { + var container = document.createElement('container'); + var renderedMarkup = React.renderToString(
); + var renderedNode; + + container.innerHTML = renderedMarkup + ' '; + + renderedNode = container.firstChild; + ReactMount.render(
, container); + expect(container.firstChild).not.toBe(renderedNode); + + container.innerHTML = ' ' + renderedMarkup; + + renderedNode = container.firstChild; + ReactMount.render(
, container); + expect(container.firstChild).not.toBe(renderedNode); + }); });