mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Adjacent text nodes in SSR should have comments between them despite components (#11109)
* Add a failing test for text nodes within components
* Reset the text node flag only when emitting tags
This ensures we don't reset it when we exit components that return strings.
* Add a failing test for a more complex tree
* Also reset text flag when emitting a footer
This fixes the {'a'}</div>{'b'} case and prevents an unnecessary comment before 'b'.
This commit is contained in:
@@ -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(<div>{'a'}<B />{'c'}</div>);
|
||||
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, [<Y key="1" />], false];
|
||||
}
|
||||
}
|
||||
|
||||
function Y() {
|
||||
return [<Z key="1" />, ['c']];
|
||||
}
|
||||
|
||||
function Z() {
|
||||
return null;
|
||||
}
|
||||
|
||||
const e = await render(
|
||||
<div>
|
||||
{[['a'], 'b']}
|
||||
<div>
|
||||
<X key="1" />
|
||||
d
|
||||
</div>
|
||||
e
|
||||
</div>,
|
||||
);
|
||||
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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user