反应路由器重定向不起作用

时间:2018-08-12 11:37:11

标签: reactjs react-router

我用服务器端渲染和2条路由设置了一个React路由器,一条路由应该将我重定向到当前“ / popular / php”的某个页面,但这不起作用,它不会将我重定向到任何地方,如果我删除重定向组件并仅在“ /”路径上呈现某些内容,则该方法有效。

我有这个路由文件。

import Home from './Home.js';
import Grid from './Grid.js';
import { fetchPopularRepos } from './api';

const routes = [
    {
        path: '/popular/:id',
        component: Grid,
        fetchInitialData: (path = '') => fetchPopularRepos (
            path.split('/').pop()
            )
    }
] 

export default routes

这是完成路由的App组件。如果我没记错的话,如果我点击“ /” URL,重定向组件应该会将我发送到“ / popular / php”页面,但是当我点击“ /” URL时什么也没有发生。

import React from 'react';
import Grid from './Grid.js';
import routes from './routes';
import { Route, Switch, Redirect } from 'react-router-dom'
import Navbar from './Navbar';
import Login from './Login';

class App extends React.Component {
    render() {
        return (
            <div>
            <Navbar />
            <Switch>
            <Route exact path="/" render={() => (
                <Redirect to="/popular/php"/>)} />
               {routes.map(({ path, exact, component: C, ...rest }) => (
                  <Route
                    key={path}
                    path={path}
                    exact={exact}
                    render={(props) => (
                      <C {...props} {...rest} />
                    )}
                  />
                ))}
             </Switch>
            </div>
            )
        }
}

export default App

Server.js

import express from 'express';
import cors from 'cors';
import { renderToString } from 'react-dom/server';
import App from '../shared/App.js';
import React from 'react';
import serialize from 'serialize-javascript';
import { matchPath, StaticRouter } from 'react-router-dom';
import routes from '../shared/routes.js';


const app = express();

app.use(cors());

app.use(express.static('public'));

app.get('*', (req, res, next) => {
    const activeRoute = routes.find(
        (route) => matchPath(req.url, route)) || {};

    const promise = activeRoute.fetchInitialData ?
            activeRoute.fetchInitialData(req.path) 
                : Promise.resolve();

    promise.then((data) => {    
        const context = { data }; 
        const markup = renderToString( 
            <StaticRouter location={req.url} context={ context }>
                <App />
        </StaticRouter>);
        res.send(`<!DOCTYPE html>
            <html>
                <head>
                    <title>SSR with RR</title>
                    <script src="/bundle.js"></script>
                    <script>window.__INITIAL_DATA__ = ${serialize(data)}</script>  
                </head>
                <body>
                    <div id="app">${markup}</div>
                </body>
            </html>`)

        }).catch(next);
})

app.listen(3000, () => {
    console.log("Server is running on port 3000");
})

1 个答案:

答案 0 :(得分:0)

将应用呈现为字符串后,您必须检查context,并查看是否发生了重定向。如果确实如此,则您必须自己进行服务器重定向。

app.get("*", (req, res, next) => {
  const activeRoute = routes.find(route => matchPath(req.url, route)) || {};

  const promise = activeRoute.fetchInitialData
    ? activeRoute.fetchInitialData(req.path)
    : Promise.resolve();

  promise
    .then(data => {
      const context = { data };
      const markup = renderToString(
        <StaticRouter location={req.url} context={context}>
          <App />
        </StaticRouter>
      );

      if (context.url) {
        res.redirect(301, context.url);
        return;
      }

      res.send(`
        <!DOCTYPE html>
        <html>
          <head>
            <title>SSR with RR</title>
            <script src="/bundle.js"></script>
            <script>window.__INITIAL_DATA__ = ${serialize(data)}</script>  
          </head>
          <body>
            <div id="app">${markup}</div>
          </body>
        </html>
      `);
    })
    .catch(next);
});