一文掌握 React Router 懒加载与路由守卫的实战

311 阅读4分钟

前言

在实际开发中,前端路由不仅仅是页面跳转那么简单。如何高效实现路由懒加载、保障页面权限、提升用户体验,是每个 React 开发者都绕不开的难题。本文将结合 Demo,深入剖析 React Router 的进阶用法,包括懒加载、路由守卫、权限鉴权等最佳实践,助你避开常见坑点,写出更健壮的前端应用。

Demo位置:deep-router

Demo 简介

本项目是一个基于React与Vite构建的组件化开发前端项目,主要用于学习和实践前端路由的深度用法,并对路由懒加载、路由守卫/鉴权(Route Guard/Protected Route)等的内容的学习。

目录结构

deep-router/
├── public/           # 静态资源目录
├── src/              # 源码目录,主要业务代码
├── index.html        # 入口 HTML 文件
├── package.json      # 项目依赖与脚本
├── vite.config.js    # Vite 配置文件
├── eslint.config.js  # ESLint 配置文件
└── README.md         # 项目说明文档

App.jsx

react_router_app.png

React Router 基础原理

React Router 是 React 生态中最主流的前端路由解决方案。它通过监听浏览器地址栏变化,决定渲染哪个组件,实现单页应用(SPA)的页面切换。

SPA

SPA可见往期文章:你不知道的前端路由实现方式与单页应用(SPA)架构模式详解

无刷新跳转

React Router可以根据不同需求,通过Hash路由或History路由来监听浏览器地址栏变化,比如:

如果服务器不需要支持前端路由,在静态页面部署,可以通过HashRouter(hash路由)用location.hash,监听hashchange实现,

又或是需要服务器支持history路由(所有路由都返回index.html),可以通过BrowserRouter(history路由)用history.pushState/replaceState,监听popstate来实现无刷新跳转

路由懒加载

我们进入一个网站时,经常会看见有占位图,或是显示正在加载中··· 的效果,其就是路由懒加载

image.png

路由懒加载 的核心思想就是:只有当用户访问某个路由时,才加载对应的页面资源(如JS、CSS等),而不是在应用初始化时一次性就加载所有页面资源,这样就能提升大型单页应用(SPA)的性能,减少首屏加载的时间并带来更好的用户体验。

懒加载模块的“引入和执行”变成按需发生,而不是一开始就全部发生, demo 中利用动态 import() 引入模块:

react_router.png

Navigate 与 Link

在 React Router(比如 react-router-dom v6)中,Navigate 和 Link 都用于页面导航,但它们的使用场景和方式不同:

Link 组件

Link常用于在JSX中渲染一个锚点(a标签),用户点击后跳转到指定路由,适合菜单、按钮、列表等地方。

Navigate 组件

Navigate 常用于在代码逻辑中“自动跳转”到指定路由,适合“条件触发”或“重定向”的场景,比如项目中的登陆后自动跳转、表单提交后跳转、权限拦截等。

前端路由鉴权

前端路由鉴权(Route Guard/Auth)是指在用户访问某些页面时,前端代码会先判断用户是否有权限(如是否登录、是否有某种角色),只有通过校验后才能进入目标页面,否则会被重定向到登录页或无权限页。

鉴权组件:

react_router_protect.png

路由守卫

路由守卫(Route Guard) 是一种在前端路由跳转时进行权限的校验的一种机制,类比就是前端密码锁,比如常见场景有:

登录校验(鉴权)

用户未登录时,访问需要登录的页面会被拦截,自动跳转到登录页,登录后可自动跳回原本想访问的页面

权限限制

不同用户角色(如普通用户、管理员)访问不同的页面或功能,只有管理员可以访问后台管理页面,普通用户访问会被重定向到无权限提示页

以及数据完整性校验、防止重复登录/注册、路由前置/后置处理等等。

项目中的路由守卫

项目中路由守卫搭配鉴权组件实现进入该页面进行访问校验,若登录则自动跳转到“守卫”的页面(即Pay),但Children是什么?

在React中,Children代表了组件标签内部包裹的内容,也就是子节点,在ProtectRoute组件中,children就是这里的<Pay />,在组件内部可以通过props.children访问到内容,再接着Navigate鉴权组件这样我们就能实现登录跳转功能。

App.jsx关于路由守卫部分:

 <Route
   path="/pay"
   element={
     <ProtectRoute>
       <Pay />
      </ProtectRoute>
     }
    />

鉴权组件:

react_router_protect.png