实现一个react-router-dom的路由拦截

实现路由守卫需要考虑到以下的问题:

  1. 未登录情况下,访问不需要权限校验的合法页面:允许访问
  2. 登陆情况下,访问登陆页面:禁止访问,跳转至主页
  3. 登陆情况下,访问除登陆页以外的合法页面:允许访问
  4. 登陆情况下,访问所有的非法页面:禁止访问,跳转至 404
  5. 未登录情况下,访问需要权限校验的页面:禁止访问,跳转至登陆页
  6. 未登录情况下,访问所有的非法页面:禁止访问,跳转至 404

react实现路由拦截的基本思路还是利用Route 的render函数。通过判断拦截条件来实现不同的组件的跳转,从而实现拦截。
首先在跟目录src下创建一个routerMap.js文件,代码如下: 
import Index from "./page/index";
import Home from "./page/home";
import ErrorPage from "./page/error";
import Login from "./page/login";
export default [
  { path: "/", name: "App", component: Index, auth: true },
  { path: "/home", name: "Home", component: Home, auth: true },
  { path: "/login", name: "Login", component: Login },
  { path: "/404", name: "404", component: ErrorPage },
];

将 auth 设置为 true,表示该路由需要权限校验。
然后,定义 Router 组件,在App.js中,该组件是经过高阶组件包装后的结果:
//App.js
import React, { Component } from "react";
import { BrowserRouter as Router, Switch } from "react-router-dom";
import FrontendAuth from "./FrontendAuth";
import routerMap from "./routerMap";
class App extends Component {
  // eslint-disable-next-line no-useless-constructor
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <Router>
        <div>
          <Switch>
            <FrontendAuth routerConfig={routerMap} />
          </Switch>
        </div>
      <

<think>好的,我现在需要解决用户关于react-router-dom v7中实现路由守卫的问题。用户之前可能已经了解过v6或其他版本的路由配置,现在升级到v7后,需要知道如何实现类似导航守卫的功能。首先,我得回忆一下react-router-dom v7的变化,尤其是相对于v6有哪些不同,因为路由守卫的实现方式可能因版本而异。 根据用户提供的引用,特别是引用[2]中的代码示例,里面提到了通过渲染路由配置和拦截的方式来实现守卫。不过,那些代码可能针对的是旧版本,比如v5或v6,因为v7中可能有一些API的变化。比如,在v6中,使用<Routes>和<Route>组件的方式与v5不同,而v7可能延续了v6的某些模式,但可能有进一步的调整。 首先,我需要确认react-router-dom v7的API。查阅官方文档,v7中推荐使用新的数据API,比如createBrowserRouterRouterProvider,这可能改变了传统的组件层次结构。在v6中,路由配置通常是通过<Routes>和<Route>组件嵌套实现的,而在v7中,可能更倾向于使用配置对象,类似于引用[2]中的示例,但需要适配新的API。 路由守卫的核心是在路由跳转前进行权限检查或其他逻辑。在React中,这通常涉及到在渲染Route组件之前进行条件判断。在类组件中,可能使用高阶组件(HOC)包装,而在函数式组件中,可以使用自定义钩子或包装组件。 用户提到的引用[3]中提到了路由传参和声明式导航,这可能与守卫无关,但需要确保在守卫逻辑中能访问路由参数或状态。例如,在检查用户权限时,可能需要获取当前的路由参数或路径。 接下来,考虑如何在v7中实现。假设v7延续了v6的useRoutes钩子,或者使用新的配置方式。可能需要创建一个包装组件,在渲染子路由前执行验证逻辑。例如,每个需要守卫的路由可以包裹在一个自定义的RouteGuard组件中,该组件接收验证函数和回退路径作为props。 在实现过程中,需要注意以下几点: 1. 如何监听路由变化:在React Router中,可以使用useLocation或useNavigate来跟踪和控制导航。 2. 如何处理异步验证:例如,需要等待API返回用户权限状态后再决定是否允许导航。 3. 如何避免无限循环:例如,当用户未登录时重定向到登录页,但登录页本身不应再次触发重定向。 可能的解决方案包括: - 使用自定义的<ProtectedRoute>组件,包裹需要守卫的路由元素。 -路由配置的element属性中使用该组件,传入权限验证逻辑和回退路径。 - 在ProtectedRoute组件内部使用useEffect或useLayoutEffect来执行验证,并根据结果进行导航。 例如,路由配置可能如下: ```javascript const router = createBrowserRouter([ { path: '/', element: <ProtectedRoute checkAuth={checkUser} redirectTo="/login" />, children: [ { path: 'dashboard', element: <Dashboard /> }, // 其他受保护路由 ] }, { path: '/login', element: <Login /> } ]); ``` 其中,ProtectedRoute组件负责执行checkAuth函数,如果失败则重定向到redirectTo路径。 此外,需要考虑如何处理嵌套路由和全局守卫。可能需要将守卫逻辑应用到父路由,使其覆盖所有子路由,或者在每个需要守卫的路由上单独应用。 另外,引用[2]中的示例使用了<Switch>组件,这在v6之后已被<Routes>取代,而v7可能继续使用<Routes>,所以需要调整代码以适应新API。例如,使用useRoutes钩子来生成路由配置,或者在createBrowserRouter中定义路由结构。 最后,需要测试不同的场景,如用户直接访问受保护路由、权限变化时的处理等,确保守卫逻辑可靠。</think>在 React Router v7 中实现路由守卫(导航守卫)可通过以下步骤完成,核心思路是**通过高阶组件封装路由元素,结合路由配置的动态渲染机制**实现权限控制。以下是具体实现方式: --- ### 一、路由守卫核心实现原理 React Router v7 延续了 v6 的声明式路由风格,但推荐使用 `createBrowserRouter` 和 `RouterProvider` 进行配置[^1]。路由守卫的关键在于: 1. **拦截路由渲染过程** 2. **执行权限校验逻辑** 3. **动态返回合法路由元素或重定向** --- ### 二、具体实现步骤 #### 步骤 1:创建路由守卫高阶组件 ```javascript // ProtectedRoute.jsx import { useEffect } from 'react'; import { useNavigate, Outlet } from 'react-router-dom'; const ProtectedRoute = ({ checkAuth, redirectPath = '/login' }) => { const navigate = useNavigate(); useEffect(() => { const verifyAuth = async () => { const isAuthenticated = await checkAuth(); if (!isAuthenticated) navigate(redirectPath); }; verifyAuth(); }, [checkAuth, redirectPath, navigate]); return <Outlet />; // 渲染子路由 }; export default ProtectedRoute; ``` #### 步骤 2:配置带守卫的路由表 ```javascript // router.js import { createBrowserRouter } from 'react-router-dom'; import ProtectedRoute from './ProtectedRoute'; import Dashboard from './Dashboard'; import Login from './Login'; const router = createBrowserRouter([ { path: '/', element: <ProtectedRoute checkAuth={() => !!localStorage.getItem('token')} />, children: [ { path: 'dashboard', element: <Dashboard /> }, { path: 'profile', element: <Profile /> } ] }, { path: '/login', element: <Login /> } ]); export default router; ``` #### 步骤 3:在根组件注入路由 ```javascript // App.jsx import { RouterProvider } from 'react-router-dom'; import router from './router'; export default function App() { return <RouterProvider router={router} />; } ``` --- ### 三、关键特性说明 1. **动态鉴权逻辑** `checkAuth` 函数支持同步/异步操作,可对接后端 API 验证权限: ```javascript checkAuth={async () => { const res = await fetch('/api/check-auth'); return res.status === 200; }} ``` 2. **自动重定向机制** 使用 `navigate(redirectPath)` 实现未授权跳转,支持相对路径与绝对路径[^3] 3. **嵌套路由守卫** 通过 `<Outlet />` 渲染子级路由,天然支持多层级守卫嵌套 --- ### 四、进阶优化方案 1. **细粒度权限控制** 为不同路由设置不同校验规则: ```javascript { path: 'admin', element: <ProtectedRoute checkAuth={checkAdmin} />, children: [...] } ``` 2. **路由加载状态处理** 添加加载动画提升用户体验: ```javascript const ProtectedRoute = () => { const [isChecking, setIsChecking] = useState(true); useEffect(() => { verifyAuth().finally(() => setIsChecking(false)); }, []); return isChecking ? <Spinner /> : <Outlet />; }; ``` 3. **白名单机制** 对公共路由免校验: ```javascript const publicPaths = ['/login', '/register']; if (publicPaths.includes(location.pathname)) return <Outlet />; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值