【问题标题】:React router redirect doesn't work反应路由器重定向不起作用
【发布时间】:2019-01-19 08:44:02
【问题描述】:

我设置了一个带有服务器端渲染和 2 个路由的反应路由器,一个路由应该将我重定向到某个页面,当前为“/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

服务器.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");
})

【问题讨论】:

  • 您如何处理服务器上的重定向? Have you read this?
  • 我用服务器代码编辑了 OP。

标签: reactjs react-router


【解决方案1】:

在将应用程序呈现为字符串后,您必须检查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);
});

【讨论】:

  • 嗯,这很简单,谢谢,我认为问题不会出现在服务器端,因为重定向应该发生在客户端,只会导致 url 发生变化。
  • @AbelTada 不客气!是的,很容易在文档中忽略它。
猜你喜欢
  • 2016-11-27
  • 2017-09-17
  • 2017-08-10
  • 2020-02-05
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多