利用 react-router4 的 react-router-config 做路由鉴权

发布于 2020-12-17 09:55:30 字数 4273 浏览 1103 评论 0

react-router-config 是一个帮助我们配置静态路由的小助手。 其源码就是一个高阶函数利用一个 map 函数生成静态路由

import React from "react";
import Switch from "react-router/Switch";
import Route from "react-router/Route";
const renderRoutes = (routes, extraProps = {}, switchProps = {}) =>
routes ? (
  <Switch {...switchProps}>
    {routes.map((route, i) => ( 
    <Route
      key={route.key || i}
      path={route.path}
      exact={route.exact}
      strict={route.strict}
      render={props => (
      <route.component {...props} {...extraProps} route={route} />
      )}
    />
    ))}
  </Switch>
  ) : null;
 export default renderRoutes;

//router.js 假设这是我们设置的路由数组(这种写法和vue很相似是不是?)

const routes = [
  { path: '/',
    exact: true,
    component: Home,
  },
  {
    path: '/login',
    component: Login,
  },
  {
    path: '/user',
    component: User,
  },
  {
    path: '*',
    component: NotFound
  }
]

//app.js 那么我们在app.js里这么使用就能帮我生成静态的路由了

import { renderRoutes } from 'react-router-config'
import routes from './router.js'
const App = () => (
   <main>
    <Switch>
     {renderRoutes(routes)}
    </Switch>
   </main>
)

export default App

扯了半天,要如何利用这个插件帮我们路由鉴权呢? 用过 vue 的小朋友都知道,vue 的 router.js 里面添加 meta: { requiresAuth: true } 然后利用 导航守卫

router.beforeEach((to, from, next) => {
  // 在每次路由进入之前判断requiresAuth的值,如果是true的话呢就先判断是否已登陆
})

基于类似 vue 的路由鉴权想法,我们稍稍改造一下 react-router-config

// utils/renderRoutes.js

import React from 'react'
import { Route, Redirect, Switch } from 'react-router-dom'
const renderRoutes = (routes, authed, authPath = '/login', extraProps = {}, switchProps = {}) => routes ? (
  <Switch {...switchProps}>
  {routes.map((route, i) => (
    <Route
    key={route.key || i}
    path={route.path}
    exact={route.exact}
    strict={route.strict}
    render={(props) => {
      if (!route.requiresAuth || authed || route.path === authPath) {
      return <route.component {...props} {...extraProps} route={route} />
      }
      return <Redirect to={{ pathname: authPath, state: { from: props.location } }} />
    }}
    />
  ))}
  </Switch>
) : null

export default renderRoutes

修改后的源码增加了两个参数 authed 、 authPath 和一个属性 route.requiresAuth 然后再来看一下最关键的一段代码

if (!route.requiresAuth || authed || route.path === authPath) {
  return <route.component {...props} {...extraProps} route={route} />
  }
  return <Redirect to={{ pathname: authPath, state: { from: props.location } }} />

很简单 如果 route.requiresAuth = false 或者 authed = true 或者 route.path === authPath(参数默认值'/login')则渲染我们页面,否则就渲染我们设置的authPath页面,并记录从哪个页面跳转。

相应的 router.js 也要稍微修改一下

const routes = [
  { path: '/',
    exact: true,
    component: Home,
    requiresAuth: false,
  },
  {
    path: '/login',
    component: Login,
    requiresAuth: false,

  },
  {
    path: '/user',
    component: User,
    requiresAuth: true, //需要登陆后才能跳转的页面

  },
  {
    path: '*',
    component: NotFound,
    requiresAuth: false,
  }
]

// app.js

import React from 'react'
import { Switch } from 'react-router-dom'
//import { renderRoutes } from 'react-router-config'
import renderRoutes from './utils/renderRoutes'
import routes from './router.js'

const authed = false // 如果登陆之后可以利用redux修改该值(关于redux不在我们这篇文章的讨论范围之内)
const authPath = '/login' // 默认未登录的时候返回的页面,可以自行设置

const App = () => (
   <main>
    <Switch>
     {renderRoutes(routes, authed, authPath)}
    </Switch>
   </main>
)
export default App
//登陆之后返回原先要去的页面login函数
login(){
  const { from } = this.props.location.state || { from: { pathname: '/' } }
   // authed = true // 这部分逻辑自己写吧。。。
  this.props.history.push(from.pathname)
}

以上~修改了部分源码并完成了我们想要的效果。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

烙印

文章 0 评论 0

singlesman

文章 0 评论 0

独孤求败

文章 0 评论 0

晨钟暮鼓

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文