diff --git a/src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js b/src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js index 642e99a0e06db..549d39858ce1d 100644 --- a/src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js +++ b/src/renderers/dom/shared/__tests__/ReactDOMServerIntegration-test.js @@ -1117,6 +1117,79 @@ describe('ReactDOMServerIntegration', () => { expectTextNode(e.childNodes[1], 'bar'); } }); + + itRenders( + 'a component returning text node between two text nodes', + async render => { + const B = () => 'b'; + const e = await render(
{'a'}{'c'}
); + if ( + render === serverRender || + render === clientRenderOnServerString || + render === streamRender + ) { + // In the server render output there's a comment between them. + expect(e.childNodes.length).toBe(5); + expectTextNode(e.childNodes[0], 'a'); + expectTextNode(e.childNodes[2], 'b'); + expectTextNode(e.childNodes[4], 'c'); + } else { + expect(e.childNodes.length).toBe(3); + expectTextNode(e.childNodes[0], 'a'); + expectTextNode(e.childNodes[1], 'b'); + expectTextNode(e.childNodes[2], 'c'); + } + }, + ); + + itRenders('a tree with sibling host and text nodes', async render => { + class X extends React.Component { + render() { + return [null, [], false]; + } + } + + function Y() { + return [, ['c']]; + } + + function Z() { + return null; + } + + const e = await render( +
+ {[['a'], 'b']} +
+ + d +
+ e +
, + ); + if ( + render === serverRender || + render === clientRenderOnServerString || + render === streamRender + ) { + // In the server render output there's comments between text nodes. + expect(e.childNodes.length).toBe(5); + expectTextNode(e.childNodes[0], 'a'); + expectTextNode(e.childNodes[2], 'b'); + expect(e.childNodes[3].childNodes.length).toBe(3); + expectTextNode(e.childNodes[3].childNodes[0], 'c'); + expectTextNode(e.childNodes[3].childNodes[2], 'd'); + expectTextNode(e.childNodes[4], 'e'); + } else { + expect(e.childNodes.length).toBe(4); + expectTextNode(e.childNodes[0], 'a'); + expectTextNode(e.childNodes[1], 'b'); + expect(e.childNodes[2].childNodes.length).toBe(2); + expectTextNode(e.childNodes[2].childNodes[0], 'c'); + expectTextNode(e.childNodes[2].childNodes[1], 'd'); + expectTextNode(e.childNodes[3], 'e'); + } + }); }); describe('number children', function() { diff --git a/src/renderers/shared/server/ReactPartialRenderer.js b/src/renderers/shared/server/ReactPartialRenderer.js index 5d128fe84da87..facf1c2bc88b9 100644 --- a/src/renderers/shared/server/ReactPartialRenderer.js +++ b/src/renderers/shared/server/ReactPartialRenderer.js @@ -475,8 +475,11 @@ class ReactDOMServerRenderer { } var frame = this.stack[this.stack.length - 1]; if (frame.childIndex >= frame.children.length) { - out += frame.footer; - this.previousWasTextNode = false; + var footer = frame.footer; + out += footer; + if (footer !== '') { + this.previousWasTextNode = false; + } this.stack.pop(); if (frame.tag === 'select') { this.currentSelectValue = null; @@ -827,6 +830,7 @@ class ReactDOMServerRenderer { frame.debugElementStack = []; } this.stack.push(frame); + this.previousWasTextNode = false; return out; } }