React路由守卫实现:基于高阶组件的路由拦截方案
本文详解React中实现路由守卫的方法。针对React Router 4.0+取消onEnter钩子的情况,介绍通过定义routerMap配置auth字段,并利用FrontendAuth高阶组件拦截Route渲染逻辑。结合localStorage判断登录状态,实现未登录跳转登录页、已登录跳转主页的完整拦截流程。
React路由守卫实现原理
与Vue框架提供内置的路由守卫不同,React实现路由拦截通常需要在路由配置中定义元数据(meta)。Vue中的beforeEnter等钩子函数用于在进入路由前进行校验,若校验失败则跳转至404或登录页;而在React中,这种机制需要开发者自行构建。
...
router.beforeEach(async(to, from, next) => {
const toPath = to.path;
const fromPath = from.path;
})
...
基于render属性的拦截思路
React实现路由拦截的核心思路是利用Route组件的render属性。通过判断特定的拦截条件,动态渲染不同的组件以实现跳转控制。在React Router 4.0之前,框架曾提供onEnter钩子,但4.0版本后改为声明式组件写法(路由即组件),因此原生的路由守卫功能被移除,需要手动实现。
import * as React from 'react';
import { HashRouter,Switch,Route,Redirect } from 'react-router-dom';
import Index from "./page/index";
import Home from "./page/home";
import ErrorPage from "./page/error";
import Login from "./page/login";
export const Router = () => (
<HashRouter>
<Switch>
<Route path="/" exact component={Index}/>
<Route path="/login" exact component={Login}/>
<Route path="/home" exact component={Home}/>
<Route path="/404" exact component={ErrorPage}/>
<Redirect to="/404" />
</Switch>
</HashRouter>
);
若不使用路由拦截,基础的Router组件结构如下所示:
上述Router组件涵盖了三个主要页面视图: 登录页 主页 404错误页 同时配置了四条路由规则: 根路径路由 登录路径路由 主页路径路由 404路径路由 其中,根路径和/home路径均指向主页组件。这是一个基础的路由配置,允许在登录、主页和404页面间自由切换,但存在安全漏洞: 用户未登录时可直接访问主页 用户已登录时仍可通过输入/login路径强制跳转至登录页 我们需要实现如下功能: 当用户未登录时,禁止直接访问主页,若尝试访问则重定向至登录路由 当用户已登录时,禁止再次访问登录页,若尝试访问则重定向至主页 实现该功能主要有两种方案: 在各组件内部通过props中的history对象手动判断跳转 采用全局路由守卫机制统一处理
路由配置与高阶组件实现
首先在src根目录下创建routerMap.js文件,代码示例如下:
/**
* 定义路由组件,将 auth 设置为 true,表示该路由需要权限校验
*/
import Admin from "./pages/Admin";
import Login from "./pages/Login";
import Error from "./pages/Error";
export const routerMap = [
{path: "/", name: "admin", component: Admin, auth: true},
{path: "/login", name: "Login", component: Login},
{path: "/error", name: "error", component: Error},
];
所有路由的渲染逻辑均交由FrontendAuth高阶组件代理执行。该组件的具体实现代码如下:
/**
* 路由守卫校验
*/
import React, {Component} from "react";
import {Route, Redirect} from "react-router-dom";
class FrontendAuth extends Component {
// eslint-disable-next-line no-useless-constructor
constructor(props) {
super(props);
}
render() {
const {routerConfig, location} = this.props;
const {pathname} = location;
const isLogin = localStorage.getItem("user");
console.log(pathname, isLogin);
console.log(location);
// 如果该路由不用进行权限校验,登录状态下登陆页除外
// 因为登陆后,无法跳转到登陆页
// 这部分代码,是为了在非登陆状态下,访问不需要权限校验的路由
const targetRouterConfig = routerConfig.find(
(item) => item.path === pathname
);
console.log(targetRouterConfig);
if (targetRouterConfig && !targetRouterConfig.auth && !isLogin) {
const {component} = targetRouterConfig;
return <Route exact path={pathname} component={component}/>;
}
if (isLogin) {
// 如果是登陆状态,想要跳转到登陆,重定向到主页
if (pathname === "/login") {
return <Redirect to="/"/>;
} else {
// 如果路由合法,就跳转到相应的路由
if (targetRouterConfig) {
return (
<Route path={pathname} component={targetRouterConfig.component}/>
);
} else {
// 如果路由不合法,重定向到 404 页面
return <Redirect to="/error"/>;
}
}
} else {
// 非登陆状态下,当路由合法时且需要权限校验时,跳转到登陆页面,要求登陆
if (targetRouterConfig && targetRouterConfig.auth) {
return <Redirect to="/login"/>;
} else {
// 非登陆状态下,路由不合法时,重定向至 404
return <Redirect to="/error"/>;
}
}
}
}
export default FrontendAuth;
接着,在App.js中定义Router组件,该组件是经过FrontendAuth高阶组件包装后的最终结果:
import './App.less';
import React, {Fragment} from "react";
import {Switch} from 'react-router-dom'
import FrontendAuth from "./FrontendAuth";
import {routerMap} from "./routerMap";
function App() {
return (
<Fragment>
{/*只匹配一个,匹配成功就不往下匹配,效率高*/}
<Switch>
<FrontendAuth routerConfig={routerMap}/>
</Switch>
</Fragment>
);
}
export default App;
测试验证

至此,关于React路由守卫(路由拦截)的实现方案介绍完毕。如需了解更多React路由相关内容,可查阅本站过往文章或继续浏览后续教程,感谢支持。
React与Vue框架选型对比:基于JavaScript前端开发视角
2026-11-04 09:50:04
React中使用Chart.js绘制动态更新饼状图
2026-11-03 22:13:19
深入理解 React 虚拟 DOM 与 Diff 算法工作原理
2026-11-03 20:15:40
详解 dva Model 结构:state、reducers 与 effects 写法指南
2026-11-03 18:15:14
排查 UmiJS 常见构建报错与路由失效问题
2026-11-03 12:47:41







