呈现在服务器上反应
我一直在试图弄清楚如何在服务器上呈现反应(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,你可以发送你的快速回复。