如果404,服务器渲染react-router v4 passthrough

Tel*_*kis 5 node.js express reactjs react-router isomorphic-javascript

在react-router v3中,我们可以知道服务器端呈现何时与当前url不匹配.这允许我将请求传递给我的express.static中间件,而不是发送渲染的应用程序.

在react-router v4中,我们必须使用

    const htmlData = renderToString(
        <StaticRouter
            location={req.url}
            context={context}
        >
            <App/>
        </StaticRouter>
    );
Run Code Online (Sandbox Code Playgroud)

为了在服务器端呈现.但是,它会自动将所有内容重定向到/.为什么这种行为甚至存在?难道我们不能像我们期望的那样错误地默默地失败吗?

我怎么知道没有任何东西匹配,以便我可以打电话next()让其他快递的路线完成这项工作?

这是我想要使用的整个功能:

app.get('*', (req, res, next) => {
    const context = {};
    const htmlData = renderToString(
        <StaticRouter
            location={req.url}
            context={context}
        >
            <App/>
        </StaticRouter>
    );

    console.log(JSON.stringify(context, null, 4)); // empty object
    if (context.url) { // <------------------------ Doesn't work (taken from example and thought it would contain the unmatched url)
        winston.info(`Passing ${req.url} along`);
        next(); // <--------------- Never called even if no route matches.
    } else {
        res.send(pageContent.replace('<div id="main"></div>',
            `<div id="main">${htmlData}</div>`));
    }
});
Run Code Online (Sandbox Code Playgroud)

我尝试过基于此的东西,但它// somewhere else是如此精确,我根本无法理解.

这是我的最后一次尝试,如果它有任何帮助.这是Router.jsx我计划定义所有Routes的文件.

import React from 'react';
import PropTypes from 'prop-types';
import {
    BrowserRouter,
    Route,
} from 'react-router-dom';
import App from './components/App.jsx';

export const Status = ({ code, children }) => (
    <Route render={({ staticContext }) => {
        if (staticContext) {
            staticContext.status = code;
        }
        return children;
    }}/>
);

Status.propTypes = {
    code     : PropTypes.number.isRequired,
    children : PropTypes.node.isRequired,
};

export const NotFound = () => (
    <Status code={404}>
        <div>
            <h1>Sorry, can’t find that.</h1>
        </div>
    </Status>
);

class Router extends React.Component {
    render() {
        return (
            <BrowserRouter>
                <div>
                    <Route exact path="/" component={App}/>
                    <Route component={NotFound}/>
                </div>
            </BrowserRouter>
        );
    }
}

export default Router;
Run Code Online (Sandbox Code Playgroud)

(我知道这根本没有任何意义,因为StaticRouter直接使用App而没有关心,Router.jsx但我根本没有Route,App所以我真的不明白如何做事,我想.

sam*_*sam 2

您应该将 NotFoundPage 组件路由逻辑放入 App.jsx 文件中,而不是您根本不使用的 Route.jsx 中。

<Switch>
    <Route exact path="/" component={AppRootComponent}/>
    <Route component={NotFound}/>
</Switch>
Run Code Online (Sandbox Code Playgroud)

除此之外,本教程代码对于使用 React Router v4 进行服务器端渲染是一个很好的参考。