【问题标题】:Server-side rendering with react-router is not working使用 react-router 进行服务器端渲染不起作用
【发布时间】:2016-05-09 08:00:09
【问题描述】:

我正在使用 express,我想做一些基本的路由服务器端。目前我只是试图设置路由器来做任何事情。现在它总是返回 404。

我相信我已经按照https://github.com/rackt/react-router/blob/master/docs/guides/advanced/ServerRendering.md 中列出的说明进行操作。

它几乎是你能得到的最基本的东西:一个快速服务器,它将每个请求路由到上面列出的链接中的代码处理,一个 ReactRouter 将所有内容路由到 AppTemplate 组件。

肯定会到达 routes.js 中的回调,因为它会为每个请求返回“未找到”。

我怀疑它是否重要,但我通过 iisnode 在 IIS 中运行它。我在调试时遇到了麻烦,这是我从 express-react-views 切换到通过 <Router> 路由的原因之一。

让我知道我可以为您提供哪些其他信息。

文件结构:

server/
-- server.js // just calls babel-register and express-app.js
-- express-app.js
-- router.js

server/views/
-- app-template.js
-- routes.js

服务器/express-app.js

import Express from 'express';
import BodyParser from 'body-parser';
import CookieParser from 'cookie-parser';

let app = new Express();
export default app;

app.enable('trust proxy');

app.use('/public', Express.static('../dist'));

app.use(BodyParser.urlencoded({ extended: true }));
app.use(BodyParser.json());
app.use(CookieParser());

// some rest API code here, currently commented out

app.set('tokenSecret', process.env.tokenSecret);

require('./router');

服务器/路由器.js

// copied right from https://github.com/rackt/react-router/blob/master/docs/guides/advanced/ServerRendering.md.
import { renderToString } from 'react-dom/server';
import { match, RouterContext} from 'react-router';

import app from './express-app';
import Routes from './views/routes';

app.get('/*', (req, res) => {
    match({ Routes, location: req.originalUrl }, (error, redirectLocation, renderProps) => {
        if (error) {
            res.status(500).send(error.message);
        } else if (redirectLocation) {
            res.redirect(302, redirectLocation.pathname + redirectLocation.search);
        } else if (renderProps) {
            res.status(200).send(renderToString(<RouterContext {...renderProps} />));
        } else {
            res.status(404).send('Not found');
        }
    });
});

server/views/routes.js

import React from 'react';
import {Router, Route, IndexRoute} from 'react-router';

import AppTemplate from './app-template';

export default (
    <Router>
        <Route path='/' component={AppTemplate}>
        </Route>
    </Router>
);

server/views/app-template.js

import React from 'react';

export default class AppTemplate extends React.Component {
    constructor() {
        super();
    }

    render() {
        return (
            <html>
                <head>
                </head>
                <body>
                    <div id='app' />
                </body>
            </html>
        );
    }
};

【问题讨论】:

    标签: react-router


    【解决方案1】:

    几周前我遇到了这个问题,但不知何故让它起作用了,以下是我做的一些不同的事情,可能会或可能不会影响您的实施:

    1. 我没有使用 express.get,而是使用了 express.use,没有指定路径,这意味着 react-router 更像是中间件而不是请求处理程序。

    2. 在第一个要匹配的参数中,我的对象键是“routes”而不是“Routes”

    3. 我也在使用“历史”模块,所以我的位置是使用 createLocation(req.originalUrl) 创建的 - createLocation 来自“历史”。

    试试这个东西,否则我也可以发布我的代码的改编版本。

    来自 OP 的说明:

    它是#2。 babel 语法{ Routes, location: req.url } 将对象扩展为具有Routes 的键,而match() 期望键为routes。这可以通过制作它来解决

    import routes from './views/routes';
    ...
    { routes, location: req.url }
    

    按照建议,或

    import Routes from './views/routes';
    ...
    { routes: Routes, location: req.url }
    

    【讨论】:

    • 你会把你的电话发给 match() 吗?在我的代码中,Routes 不是关键;它是一个对象,对我来说看起来很奇怪,但它以某种方式在 Babel 中解析。我保持原样是因为它在文档中是这样的。
    • 我做了这三个更改,但得到了相同的结果。
    • 从头开始。我进行了另一项更改,使其无法正常工作。问题是#2。对象扩展语法导致变量名“Routes”成为键,就像你说的那样,match() 期望键是小写的。
    猜你喜欢
    • 2016-08-06
    • 2015-08-18
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 2016-01-27
    • 2019-10-02
    相关资源
    最近更新 更多