渲染在服务器上反应

时间:2015-12-22 03:37:18

标签: node.js express reactjs

我一直试图弄清楚如何在服务器上呈现反应(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变压器老了,但我觉得我有最新版本

我没有想法

3 个答案:

答案 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作为字符串,您可以在明确的回复中发送。