简体   繁体   English

ReactJS服务器端渲染问题

[英]ReactJS server-side rendering issue

Please help me to understand my issue. 请帮助我了解我的问题。

I have the following on the server -side (Node.js): 我在服务器端(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 如果template包含字符串

'<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. 您永远不能像呈现JSX一样呈现纯HTML。 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. 相反,您应该在呈现服务器时将其作为页面源的一部分包含在服务器呈现的HTML中,然后使用与服务器上使用的相同的道具初始化客户端React应用程序。

So, for example, using the EJS template engine: 因此,例如,使用EJS模板引擎:

// 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. 有关更多信息,请参见如何实现节点+ React同构JavaScript及其重要性

The problem with your code is that you send just a div tag without a real document. 代码的问题在于,您只发送了一个div标签而没有真实的文档。 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 . 您正在尝试将组件安装在具有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. 但是您错过了在服务器端呈现的组件中添加具有id 容器的元素的功能。
To achieve this use a template like Jade . 要实现此目的,请使用Jade之类的模板。

div(class="container")

renderedHTMLString renderHTMLString

If u want to replace entire body just add this client side. 如果您要替换整个机身,只需添加此客户端即可。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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