简体   繁体   中英

ReactJS server-side rendering issue

Please help me to understand my issue.

I have the following on the server -side (Node.js):

var React = require('react');
var ReactDOMServer = require('react-dom/server');

var TestComponent = React.createClass({
  render : function() {
    return <div>test</div>
  }
});

// express router callback..
function(req, res, next) {
  res.send(ReactDOMServer.renderToString(TestComponent));
};

An example of response :

<div data-reactid=".2e2hyaaz0n4" data-react-сhecksum="1124798100">test</div>

And on the client -side:

ReactDOM.render(React.createElement(template), document.getElementById('container'));

I'm having the following error in browser console:

Uncaught Invariant Violation: Invalid tag: <div data-reactid=".2e2hyaaz0n4" data-react-checksum="1124798100">test</div>

Any help will be appreciated!

If template contains the string

'<div data-reactid=".2e2hyaaz0n4" data-react-сhecksum="1124798100">test</div>'

then this is not quite correct. You can never render plain HTML as if it were JSX. Instead you should include the server-rendered HTML as part of the page source when it is rendered, and then initialize the client-side React application using the same props as used on the server.

So, for example, using the EJS template engine:

// In Express

function(req, res, next) {
  var reactHtml = ReactDOMServer.renderToString(<TestComponent />);
  res.render('index.ejs', {reactOutput: reactHtml});
};
<!-- In a template somewhere -->
<div id="container"><%- reactOutput %></div>
// In a client-side JavaScript file

var TestComponent = React.createClass({
  render : function() {
    return <div>test</div>
  }
});

ReactDOM.render(<TestComponent />, document.getElementById('container'));

See How to Implement Node + React Isomorphic JavaScript & Why it Matters for more information.

The problem with your code is that you send just a div tag without a real document. This means that on the server you should write something like this:

function(req, res, next) {
  const component = ReactDOMServer.renderToString(TestComponent);

  const layout = `<!DOCTYPE html>
    <html>
      <head lang="en">
        <meta charSet="utf-8"/>
        <title>Isomorphic app</title>
      </head>
      <body>
        <div id="container">${component}</div>
      </body>
    </html>`;

  res.send(layout);
};

Also you can check out this repo with an example of simple isomorphic app.

You are trying to mount the component on the element having id container .

ReactDOM.render(React.createElement(template), document.getElementById('container'));

But you missed to add the element with id container in the component rendered from serverside.
To achieve this use a template like Jade .

div(class="container")

renderedHTMLString

If u want to replace entire body just add this client side.

ReactDOM.render(React.createElement(template), document.getElementsByTagName('body')[0]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM