React: ReactDOM renderToString adds empty HTML comments

Created on 30 Jan 2019  路  3Comments  路  Source: facebook/react

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
ReactDOM.renderToString adds an empty HTML comment.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

const someVar = 'foo';

const htmlWithVariableAndCharacters = document.createTextNode(
  ReactDOMServer.renderToString(
    <div>{someVar}anyCharacters</div>
  )
);

document.body.appendChild(htmlWithVariableAndCharacters);

HTML Output:

<div data-reactroot="">foo<!-- -->anyCharacters</div>

See it live here: https://codepen.io/anon/pen/mvORKd?editors=0010

What is the expected behavior?
Expected HTML output:

<div data-reactroot="">fooanyCharacters</div>

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
Seen in React 16.7.0, do not know behavior in previous versions.


Something to keep in mind is if you open Chrome Development Tools you will not be able to see these HTML comments as Chrome strips them from being viewed in the developer pane. They can be seen in a server side render string output or if you right-click and choose 'Copy Element' and paste into a text editor.

Most helpful comment

@gaearon Oh, very interesting.

Note for folks that somehow land here, if you want to avoid the extra characters, particularly in long lists of things which can add up to thousands of characters can switch from something like:

Before

const someVar = 'foo';

const htmlWithVariableAndCharacters = document.createTextNode(
  ReactDOMServer.renderToString(
    <div>{someVar}anyCharacters</div>
  )
);

document.body.appendChild(htmlWithVariableAndCharacters);
// Output: <div data-reactroot="">foo<!-- -->anyCharacters</div>

After

const htmlWithVariableAndNoCharacters = document.createTextNode(
  ReactDOMServer.renderToString(
    <div>{`${someVar}anyCharacters`}</div>
  )
);

document.body.appendChild(htmlWithVariableAndNoCharacters);
// Output: <div data-reactroot="">fooanyCharacters</div>

Suspicion is this could be a candidate for Node.normalize()? If that was called before render to compact the text nodes, would it then still be necessary to use the HTML comment trick to end up with the same output? Thinking out loud here.. https://developer.mozilla.org/en-US/docs/Web/API/Node/normalize

Had this showing up in two places in a list of 100 things:
<!-- --> = 8 characters * 2 spots * 100 list items = 1600 extra characters

Gzip does eat this up though for sure, just seemed a bit odd. @gaearon thanks for the clarity!

All 3 comments

This is by design and helps React hydrate those text nodes correctly.

@gaearon Oh, very interesting.

Note for folks that somehow land here, if you want to avoid the extra characters, particularly in long lists of things which can add up to thousands of characters can switch from something like:

Before

const someVar = 'foo';

const htmlWithVariableAndCharacters = document.createTextNode(
  ReactDOMServer.renderToString(
    <div>{someVar}anyCharacters</div>
  )
);

document.body.appendChild(htmlWithVariableAndCharacters);
// Output: <div data-reactroot="">foo<!-- -->anyCharacters</div>

After

const htmlWithVariableAndNoCharacters = document.createTextNode(
  ReactDOMServer.renderToString(
    <div>{`${someVar}anyCharacters`}</div>
  )
);

document.body.appendChild(htmlWithVariableAndNoCharacters);
// Output: <div data-reactroot="">fooanyCharacters</div>

Suspicion is this could be a candidate for Node.normalize()? If that was called before render to compact the text nodes, would it then still be necessary to use the HTML comment trick to end up with the same output? Thinking out loud here.. https://developer.mozilla.org/en-US/docs/Web/API/Node/normalize

Had this showing up in two places in a list of 100 things:
<!-- --> = 8 characters * 2 spots * 100 list items = 1600 extra characters

Gzip does eat this up though for sure, just seemed a bit odd. @gaearon thanks for the clarity!

@buildbreakdo woah thx mate! Took me ages to find someone with the same problem. I use react as content building tool where the render output is imported into a more or less standardized software solution and those comments killed the upload.

Was this page helpful?
0 / 5 - 0 ratings