呈现在服务器上反应

我一直在试图弄清楚如何在服务器上呈现反应(node / express),最后find一个足够简单的教程来理解正在发生的事情。 但是现在,在设置好所有东西之后,我在React.render方法中收到错误:

这是我的组件文件:

 var React = require('react'); var box = React.createClass({ render: function() { return ( <div style='padding: 10px'> this.props.text </div> ); } }); React.render(<box text='testing server side'/>, document.body); module.exports = box; 

当我运行npm start时出现错误:

文件没有定义

我如何解决这个问题? 我需要还是不需要渲染方法?

为了给出更多的上下文,这个box组件正在被另一个组件需要:

 var React = require('react'); var Box = require('../react-jsx/box.js'); //this is the box component var Component = React.createClass({ render: function() { return ( <html> <head> <title> React Server Rendering </title> </head> <body> <Box text='testing'/> <script src="public/bundle.js"></script> </body> </html> ); } }); module.exports = Component; 

这在index.js中已经被使用了

 require('node-jsx').install(); var React = require('react'); var Component = require('../custom-modules/test-react-server-module.js'); var express = require('express'); var router = express.Router(); router.get('/react', function(req, res, next) { var markup = React.renderToString(Component()); res.send(markup); }); module.exports = router; 

如果我删除渲染方法,我得到这个错误在浏览器中:

无法读取未定义的属性'__reactAutoBindMap'

我看到有人说可能是由于jsx变压器老了,但我想我有最新版本

我没有想法

首先,我build议更新你的React版本。 目前的版本公开了两个不同的顶级API: React ,通常用于创build组件和ReactDOM ,它将暴露特定于DOM的方法用于应用程序的顶层。

有需要指出的地方在这里:

  • 你正试图运行一个应该只在浏览器上执行的代码。 NodeJS中没有文档 。 我build议使用webpack打包这个组件文件并在浏览器上提供它们。

  • 对于一个同构React应用程序,您需要有一个client.js文件,该文件调用您正试图在index.js呈现的相同组件的渲染函数。 得到它了?

了解ReactDOM.render ,如文档所述:

将ReactElement渲染到提供的容器中的DOM中,并返回对组件的引用(或者为无状态组件返回null)。

如果ReactElement先前已被渲染到容器中,则会对其执行更新,并且仅根据需要对DOM进行变更以反映最新的React组件。

再次记住,ReactDOM.render应该只在应用程序的顶层使用几次,而且一次只能使用一次。

说了这些,你的box.js应该是这样的:

 var React = require('react'); var box = React.createClass({ render: function() { return ( <div style='padding: 10px'> this.props.text </div> ); } }); module.exports = box; 

为了正确的工作,你需要创build一个主要组件main-component-file.js

 var React = require('react'); var Box = require('../react-jsx/box.js'); //this is the box component var Component = React.createClass({ render: function() { return ( <html> <head> <title> React Server Rendering </title> </head> <body> <Box text='testing'/> <script src="public/bundle.js"></script> </body> </html> ); } }); module.exports = Component; 

在你的bundle.js你需要确保这个被调用,所以主要组件试图重新渲染:

 var React = require('react'); var ReactDOM = require('react-dom'); var Component = require('main-component-file.js'); ReactDOM.render(<Component/>, document.body); 

最后但并非最不重要的:服务器文件index.js 。 将ReactDOMServer.renderToString更改为ReactDOMServer.renderToString ,从主要组件创build一个React元素并使用它:

 var element = React.createElement(Component) router.get('/react', function(req, res, next) { var markup = ReactDOMServer.renderToString(element); res.send(markup); }); 

不要忘记在你的index.js包含npm包react-dom/server

文章中使用的参考文献:

  • React.createElement

  • ReactDOM.render()文档

  • ReactDOMServer文档

你应该删除这个

 React.render(<box text='testing server side'/>, document.body); 

这是没有必要的。 你实际上告诉React要做的就是在那里和那里进行渲染。

document.body还不存在,因为你正在渲染它在服务器端,你也不需要它,因为你在router根据请求在renderToString函数中渲染组件。 (另外我认为@PeterLyons是正确的,所以看看他的答案)。

另外,如果您仅严格使用React来查看视图,则可能需要查看express-react-views 。 他们有一个关于如何使用React with Express的很好的教程,你基本上只能用它来进行服务器端的渲染。 我不认为这是使用react-router理想方式,这取决于你正在构build的东西,但它说明了React如何处理服务器端的渲染,并且和Express一起工作。

您需要在服务器环境中使用react-dom/server包的renderToString函数。 这将返回HTML作为一个string,你可以发送你的快速回复。