React 路由守卫

11,754 阅读2分钟

React 路由守卫

关键词:

  • React
  • Router
  • Router Guard
  • 路由守卫

环境

react 16.12.0
react-router-dom 5.1.2

React的路由守卫与Vue的路由守卫不太相同,并没有像Vue那样提供类似beforeEach的钩子,而是需要我们自己封装一个组件,一开始接触React的同学可能会感觉奇怪,认为组件只是像Vue那样封装主要聚焦于界面的代码块,这其中也包括我。

主要逻辑就是,
判断路由(是否是根路由/,是否是登录页,是否是需要登录权限的页面,是否是非法路由),根据不同的路径,返回不同的组件或使用组件重定向路由。

FrontendAuth.js

此处,将路由配置单独抽出配置了。
如果你需要可以继续在RouterConfig.js文件中添加路由配置,不过不支持像Vue那样那么多样的配置,仅仅是为了方便个人抽出而已。
如果你不需要,可以逻辑中返回你需要的组件。

import React from "react";
import { Route, Redirect } from "react-router-dom";

// config
import RouterConfig from "./RouterConfig";

class FrontendAuth extends React.Component {
  render() {
    const pathname = this.props.location.pathname;
    const targetRouter = RouterConfig.find(function(item) {
      return item.path === pathname;
    });
    const isLogin = JSON.parse(sessionStorage.getItem("loginStatus"));

    if (pathname === "/") {
      return <Redirect to="login"></Redirect>;
    }

    if (!targetRouter) {
      return <Redirect to="404" />;
    }

    if (isLogin) {
      if (pathname === "/login") {
        return <Redirect to="/home"></Redirect>;
      } else {
        return (
          <Route exact path={pathname} component={targetRouter.component} />
        );
      }
    } else {
      if (targetRouter.auth) {
        console.log("请先登录");
        return <Redirect exact to="/login" />;
      } else {
        return (
          <Route exact path={pathname} component={targetRouter.component} />
        );
      }
    }
  }
}

export default FrontendAuth;

RouterConfig.js

import Login from "../components/Login";
import Home from "../components/Home";
import NotFound from "../components/NotFound";

const RouterConfig = [
  {
    path: "/login",
    component: Login,
    auth: false
  },
  {
    path: "/home",
    component: Home,
    auth: true
  },
  {
    path: "/404",
    component: NotFound,
    auth: false
  }
];

export default RouterConfig;

App.js

import React from "react";
import { HashRouter, Switch } from "react-router-dom";
import FrontendAuth from "./utils/FrontendAuth";

class Demo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {
    return (
      <HashRouter>
        <Switch>
          <FrontendAuth></FrontendAuth>
        </Switch>
      </HashRouter>
    );
  }
}

export default Demo;

完整Demo代码
Github:github.com/blueju/Blog…
代码在npm install后可直接运行,本人已经跑通过的。

但是有个问题,
如果你注意控制台的话,会发现,console会触发两次,但在实际使用Ant Design的message时,并没有出现连弹两个message弹框的问题。

总的一句话,
就是React中,并没有那么多像Vue的配置,更多的是需要自己判断逻辑去控制返回你想要的组件。

首发于语雀文档@blueju