React Router 在一个重定向中包装多个路由
Posted
技术标签:
【中文标题】React Router 在一个重定向中包装多个路由【英文标题】:React Router Wrap Multiple Routes in a Redirect 【发布时间】:2019-07-28 15:58:45 【问题描述】:给定一个身份验证令牌和一个函数 checkToken
我将如何使用 react 路由器从多个路由重新路由以防止重复如下?
<Route exact path="/" render=() =>
return checkToken() ? (<Dashboard />) : (<Redirect to="/login" />)
/>
<Route exact path="/about" render=() =>
return checkToken() ? (<About />) : (<Redirect to="/login" />)
/>
如果我有几十条路线要重复这个,那会很麻烦。
肯定有更好的办法!
【问题讨论】:
您熟悉高阶组件 (HOC) 模式吗? 【参考方案1】:这是我喜欢的处理方式:
-
在
src
中创建一个routers
文件夹
在路由器文件夹内创建3个文件AppRouter.js
, PrivateRoute.js
& PublicRoute.js
这是你的PublicRoute.js
:
import React from 'react';
import connect from 'react-redux';
import Route, Redirect from 'react-router-dom';
export const PublicRoute = ( isAuthenticated, component: Component, ...rest ) => (
<Route ...rest component=(props) => (
isAuthenticated ? <Redirect to="/dashboard" /> : <Component ...props />
) />
);
const mapStateToProps = state => (
isAuthenticated: // however you need to keep track of that...
);
export default connect(mapStateToProps)(PublicRoute);
这是你的PrivateRoute.js
:
import React from 'react';
import connect from 'react-redux';
import Route, Redirect from 'react-router-dom';
export const PrivateRoute = ( isAuthenticated, component: Component, ...rest ) => (
<Route ...rest component=(props) => (
isAuthenticated ? <Component ...props /> : <Redirect to="/" />
) />
);
const mapStateToProps = state => (
isAuthenticated: // however you need to keep track of that...
);
export default connect(mapStateToProps)(PrivateRoute);
最后是你的AppRouter.js
:
import React from 'react';
import BrowserRouter, Route, Switch from 'react-router-dom';
import Dashboard from '../components/Dashboard';
import NotFound from '../components/NotFound';
import Login from '../components/Login';
import PrivateRoute from './PrivateRoute';
import PublicRoute from './PublicRoute';
const AppRouter = () => (
<BrowserRouter>
<Switch>
/* use PublicRoute for public routes */
<PublicRoute exact path="/" component=Login />
/* use PrivateRoute for private routes */
<PrivateRoute path="/dashboard" component=Dashboard />
<Route component=NotFound />
</Switch>
</BrowserRouter>
);
export default AppRouter;
有关 HOC(高阶组件)的更多信息,请查看文档:https://reactjs.org/docs/higher-order-components.html
【讨论】:
这似乎是合理的,但它不是增加了很多样板而不是减少了吗? @calben 我想这取决于您的应用程序和用例...这里的想法是创建这两个 HOC,然后在您的实际AppRouter
中简单地使用 PublicRoute
或 PrivateRoute
HOC 而不是 Route
(我们从 lib 中获得)...当然,如果您只有 2 个组件(仪表板和登录),这有点矫枉过正...【参考方案2】:
实现它的一种方法是将您的 checkToken 函数放在 componentDidMount 中,这样您每次安装该组件时都会检查您的用户是否经过身份验证。
之后你可以这样做:
let routes = (
<Switch>
<Route path="/login" component=LoginComponent />
<Redirect to="/" />
</Switch>
);
if (isAuth)
routes = (
<Switch>
<Route path="/yourRoute" component=YourComponent />
<Redirect to="/" />
</Switch>
);
return (
<div>
routes
</div>
【讨论】:
以上是关于React Router 在一个重定向中包装多个路由的主要内容,如果未能解决你的问题,请参考以下文章
反应:'重定向'不是从'react-router-dom'导出的