React-router 5.2.0 + React 16.13.1 路由守卫的简单实现

这几天从Vue转react,学习一下全家桶。

React-router很强大, 但是文档是纯英文而且不直接提供类似Vue的路由守卫,所以需要手写路由守卫,下面是一个写法,可参考,路由守卫的作用都知道,就不再赘述,最基础的功能就是对登录状态进行一个简单的验证。


首先创建几个页面:

  1. Home:主页

  2. Login:登录

  3. Error:路由出错的展示页面(404)

然后创建router.js用来编写路由配置

步骤:

1.import必要的组件:

import React from 'react';
import Login from './Login/index.js';
import Home from './Home/index.js';
import ErrorPage from './Error/index.js';
import {
  BrowserRouter as Router ,
  Switch ,
  Route ,
  useHistory ,
  useLocation,
  Redirect
} from 'react-router-dom';

2.配置路由数组:

const routerArr = [
  {
      path:"/login",
      component:Login,
  },
  {
      path:"/error",
      component:ErrorPage
  },
  {
      path:"/",
      component:Home
  }
]

3.编写路由守卫:

function RouterGuard(){
  let history = useHistory();
  let location = useLocation();
  // 拿到路径
  let { pathname } = location;
  // 拿到当前路由
  let thisRoute = routerArr.find((el)=>el['path'] == pathname);
  let isLogin = sessionStorage.getItem('isLogin');
  //如果没登录且页面为登录页的话渲染登录页
  if(pathname == '/login' && !isLogin){
    return <Route path={pathname} component={thisRoute['component']} exact/>
  }
  //如果已经登录渲染页面
  if(isLogin){
    //如果登陆了跳转login页,则重定向
    if(pathname == '/login'){
      return <Redirect to="/" />
    }
    // 判定路由是否存在,如果存在正常渲染
    if(thisRoute){
      return <Route path={pathname} component={thisRoute['component']} exact/>
    }else{
      //否则进入404页面
      return <Redirect to="/error" />;
    }
  }else{
    // 否则跳转到登录页
    return <Redirect to="/login" />
  }
}

可以做更多的拓展,比如通过在路由配置中添加字段实现传值/条件跳转等功能

4.渲染Router并抛出组件:

function Routes(){
  return (
    <Router>
      <Switch>
        <RouterGuard />
      </Switch>
    </Router>
  )
}
export default Routes

然后渲染即可,子组件均可通过:

this.props.history 
this.props.location

等方式的到父组件的方法,方便进行跳转等调用。

完整的Router.js:

import React from 'react';
import Login from './Login/index.js';
import Home from './Home/index.js';
import ErrorPage from './Error/index.js';
import {
  BrowserRouter as Router ,
  Switch ,
  Route , 
  useHistory ,
  useLocation,
  Redirect
} from 'react-router-dom';
const routerArr = [
  {
      path:"/login",
      component:Login,
  },
  {
      path:"/error",
      component:ErrorPage
  },
  {
      path:"/",
      component:Home
  }
]
​
function RouterGuard(){
  let history = useHistory();
  let location = useLocation();
  let { pathname } = location;
  // 拿到当前路由
  let thisRoute = routerArr.find((el)=>el['path'] == pathname);
  let isLogin = sessionStorage.getItem('isLogin');
  //如果没登录且页面为登录页的话渲染登录页
  if(pathname == '/login' && !isLogin){
    return <Route path={pathname} component={thisRoute['component']} exact/>
  }
  //如果已经登录渲染页面
  if(isLogin){
    //如果登陆了跳转login页,则重定向
    if(pathname == '/login'){
      return <Redirect to="/" />
    }
    if(thisRoute){
      return <Route path={pathname} component={thisRoute['component']} exact/>
    }else{
      return <Redirect to="/error" />;
    }
  }else{
    // 否则跳转到登录页
    return <Redirect to="/login" />
  }
}
function Routes(){
  return (
    <Router>
      <Switch>
        <RouterGuard />
      </Switch>
    </Router>
  )
}
export default Routes

猜你喜欢

转载自blog.csdn.net/weixin_41564885/article/details/108469132