我一直试图弄清楚如何在服务器上呈现反应(node / express),最后找到一个简单的教程来了解正在发生的事情。但现在,在设置完所有内容后,我在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;
如果我删除了渲染方法,我在浏览器中收到此错误:
无法读取属性&#39; __ reactAutoBindMap&#39;未定义的
我看到有人说这可能是因为jsx变压器老了,但我觉得我有最新版本
我没有想法
答案 0 :(得分:10)
首先,我建议您更新您的React版本。当前版本公开了两种不同的顶级API: React ,它通常用于创建组件, ReactDOM ,它公开了在顶级使用的特定于DOM的方法你的应用程序。
这里需要指出的事情:
您正在尝试运行应该仅在浏览器上执行的代码。 NodeJS中没有文档。我建议使用webpack
打包此组件文件并在浏览器上提供。
对于同构React应用程序,您需要一个client.js
文件,该文件为您尝试在index.js
内呈现的同一组件调用render函数。知道了吗?
了解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;
为了使其正常工作,您需要创建一个主要组件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
,服务器文件。将React.renderToString
更改为ReactDOMServer.renderToString
,从主要组件创建React元素并使用它:
var element = React.createElement(Component)
router.get('/react', function(req, res, next) {
var markup = ReactDOMServer.renderToString(element);
res.send(markup);
});
不要忘记在react-dom/server
添加npm包index.js
。
文章中使用的参考文献:
答案 1 :(得分:1)
你应该删除这个
React.render(<box text='testing server side'/>, document.body);
没有必要。你基本上告诉React要做的就是在那里和那里进行渲染。
document.body
尚不存在,因为您在服务器端呈现它而且您也不需要它,因为您在renderToString
函数中根据请求在router
函数中呈现该组件}。 (我也认为@PeterLyons是正确的,所以看看他的答案也是如此)。
此外,如果您严格仅针对视图使用React,则可能需要查看express-react-views。他们有一个很好的教程,如何使用React与Express,你基本上只能用它来进行服务器端渲染。我认为它不像使用react-router
那样理想,这取决于你正在构建的内容,但它说明了React如何处理服务器端渲染并与Express一起使用。
答案 2 :(得分:0)
您需要在服务器环境中使用react-dom/server
包的renderToString功能。这将返回HTML作为字符串,您可以在明确的回复中发送。