--- tags: [frontend, react, react-router, routing, spa] create time: 2026-04-25 15:30 --- # 路由原理:BrowserRouter 与组件协作 ## 概述 本文梳理 React Router 的核心组件如何配合完成单页应用(SPA)的路由跳转。重点理解 `` 作为"路由引擎"的作用,以及 `NavLink`、`Routes`、`Route`、`Navigate` 等组件的职责分工。 --- ## 正文 ### `` 的核心作用 `` 就是 React Router 的**"总开关"和"运行环境"**,没有它,路由组件无法正常工作。 ```tsx ``` 它做三件事: 1. **提供路由上下文** — 让 `Routes`、`Route`、`NavLink` 知道当前路径是什么、该显示哪个页面 2. **无刷新切换页面** — 基于浏览器的 `History API`,URL 变了但整页不会刷新 3. **全局可用** — 因为它包住了 ``,其所有子组件都能使用路由能力 > 💡 **想一想**:为什么 `` 必须包裹 `` 而不是只包某个子组件? > > 如果它只包了 `` 但没有包 ``,点击导航按钮会报错: > > ``` > Uncaught Error: useHref() may be used only in the context of a component > ``` > > 因为 `NavLink` 内部通过 React Context 读取路由数据,如果它处于 `` 之外,就**读不到任何路由信息**,只能直接崩溃。 ### 组件职责类比 | 组件 | 类比角色 | 一句话说明 | |------|---------|-----------| | `` | 交通系统 | 提供整个路由的运行环境 | | `NavLink` | 路牌 / 入口 | 用户点击后触发路径切换 | | `Routes` | 调度中心 | 读取当前路径,决定走哪条路 | | `Route` | 目的地 | 定义"路径 → 页面"的映射 | | `Navigate` | 自动转弯 | 把用户重定向到另一个路径 | ### 路由流程 当用户点击左侧导航栏的"课程管理"时,背后发生了什么? ```mermaid flowchart LR A[用户点击 NavLink] --> B[URL 变为 /courses] B --> C[Routes 读取当前路径] C --> D{匹配哪个 Route?} D -->|path=/courses| E[渲染 CoursesPage] D -->|无匹配| F[不显示任何页面] E --> G[页面切换完成,整页未刷新] ``` 逐帧拆解: 1. `NavLink to="/courses"` 将浏览器地址变为 `/courses` 2. `Routes` 读取当前路径 3. 匹配到 `} />` 4. `CoursesPage` 组件渲染 整个过程**地址栏变了、组件切换了、但页面没有刷新**。 ### 实际代码中的用法 **路由声明**(`App.tsx`): ```tsx // 根路径自动跳转到 dashboard(replace 不留后退痕迹) } /> // 正常路由映射 } /> } /> ``` **导航链接**: ```tsx 课程管理 ``` **解读**:`} />` 表示当用户访问根路径 `/` 时,自动跳转到 `/dashboard`。`replace` 参数会让浏览器用新路径替换当前历史记录,这样用户按"后退"按钮不会回到登录页。 ### 为什么不能去掉 ``? 路由组件需要"上下文"才知道当前路径是什么、该往哪里跳。如果去掉 ``: - `NavLink` 不知道点击后该跳到哪里 - `Route` / `Routes` 不知道当前路径是什么 - `Navigate` 无法执行跳转 它们会直接报错。 > 💡 **想一想**:如果我们不用 ``,还有哪些方式能让路由组件知道当前路径?(提示:URL 地址栏本身就是公开的,React Router 还提供了 `HashRouter` 和 `MemoryRouter`,它们分别适用于什么场景?) --- ## 关联笔记 - [[金山办公作业/Week06/登录安全流程]] - 用户认证与 JWT Token - [[Outlet]] - 嵌套路由的出口 / 占位符