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