node.js - 在服务器上渲染 react

标签 node.js express reactjs

我一直在努力弄清楚如何在服务器( Node/ express )上使用react,最后找到了一个足够简单的教程来理解发生了什么。但是现在,在设置好所有内容之后,我在 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 时出现错误:

document is not defined

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

为了提供更多上下文,另一个组件需要此 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;

如果我删除渲染方法,我会在浏览器中收到此错误:

Cannot read property '__reactAutoBindMap' of undefined

我看到有人说可能是因为 jsx transformer 太旧了,但我想我有最新版本

我没有想法

最佳答案

首先,我建议更新您的 React 版本。当前版本公开了两个不同的顶级 API:React,通常用于创建组件和 ReactDOM,它公开了要在顶级使用的特定于 DOM 的方法您的应用程序。

这里有几点需要指出:

  • 您正在尝试运行本应仅在浏览器中执行的代码。 NodeJS 中没有文档。我建议使用 webpack 打包这个组件文件并在浏览器上提供它们。

  • 对于同构 React 应用程序,您需要有一个 client.js 文件,该文件为您尝试在 index.js< 中呈现的同一组件调用呈现函数。明白了吗?

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

Render a ReactElement into the DOM in the supplied container and return a reference to the component (or returns null for stateless components).

If the ReactElement was previously rendered into container, this will perform an update on it and only mutate the DOM as necessary to reflect the latest React component.

请再次记住,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);
});

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

文章中使用的引用资料:

关于node.js - 在服务器上渲染 react ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34408059/

相关文章:

Javascript:如何通过单义键并基于属性合并两个数组?

javascript - 响应属性不适用于 react-slick

facebook - React Native 错误 - yarn' 未被识别为内部或外部命令

node.js - npm 安装失败,因为 node-gyp 失败。怎么修?

javascript - NodeJSencodeURI 为 ß 生成错误的结果

javascript - 如何在 Express 中访问 res.render 中的数据

javascript - Serverless express 关闭 mongodb 连接

node.js - node.js 中 res.setHeader 和 res.header 的区别

javascript - Express webapp如何存储/访问用户设置

javascript - webpack 4 uglifyjs 没有缩小和压缩