React Router

核心判断

  • React Router 的核心不是“页面跳转 API”,而是把 URL 当成应用状态,把路由树当成 UI 结构,把导航当成状态切换。
  • 学 React Router 的主线应从三层递进:先理解 URL 如何映射视图,再理解路由如何组织布局与数据,最后理解路由如何成为代码分割、SSR、微前端等架构边界。
  • 现代 React Router 的关键变化是“数据路由”:路由不只决定渲染哪个组件,也开始承载数据加载、提交、错误处理与导航状态。

这个主题要回答的问题

  • React Router 解决的核心问题是什么?
  • 为什么说 URL、路由树、UI 布局树应放在同一个模型里理解?
  • 什么时候使用组件式路由,什么时候使用数据路由?
  • params、search、location state 分别适合表达哪类状态?
  • React Router 如何进入更大的前端架构问题,例如懒加载、SSR、微前端和渐进式集成?

主题结构

1. 路由的基础模型:URL 是可分享的应用状态

  • URL 状态化:React Router 的第一层心智模型,是把 pathname、search、hash 与 history 都看作可导航、可回退、可分享的状态来源。
  • 路由历史模式:BrowserRouter、HashRouter、MemoryRouter 的差异,本质是“导航状态存在哪里、谁负责响应变化”。
  • 可分享、可刷新后恢复的状态优先放进 URL;只在本次跳转中临时使用的上下文,才适合放进 location state。

2. 路由树的组织模型:路由结构映射 UI 布局结构

  • 路由树即布局树:父路由负责稳定布局,子路由通过 <Outlet /> 填充变化区域,嵌套路由因此成为组织页面结构的方式。
  • index 路由、动态路由、通配路由、布局路由分别处理默认内容、资源详情、兜底匹配与共享布局。
  • 当嵌套路由和 UI 结构不一致时,路由表会从“页面结构描述”退化成“跳转配置堆”。

3. 导航模型:声明式导航优先,命令式导航用于流程跳转

  • Link / NavLink 更适合 UI 层导航,因为它们保留了链接语义、可预期历史记录与激活状态。
  • useNavigate 更适合登录成功、提交后跳转、返回上一页、替换历史记录等流程控制。
  • 过度使用命令式导航,通常意味着把本应由链接表达的信息架构藏进了事件逻辑。

4. 状态表达模型:路径参数、查询参数与导航状态各有边界

  • 路由状态分层:路径参数表达资源身份,查询参数表达筛选、排序、分页等可分享状态,location state 表达一次性导航上下文。
  • useParams 适合读取 /posts/:postId 这类资源标识;useSearchParams 适合维护搜索词、筛选条件、分页游标等 URL 状态。
  • 把筛选、排序、分页长期放在组件本地 state,会削弱链接分享、刷新恢复和浏览器历史行为。

5. 数据路由模型:路由成为数据读取、提交与错误处理边界

  • 数据路由loaderactionerrorElement 让数据依赖、表单提交和错误边界跟随路由层级,而不是散落在组件内部的 useEffect 中。
  • 组件式路由适合简单应用和入门理解;数据路由更适合中大型应用,因为它把页面进入前的数据依赖声明在路由层。
  • 数据路由的价值不只是“少写请求代码”,而是把导航、加载、提交、错误恢复放进同一套页面生命周期模型里。

6. 架构边界:路由是加载、拆分与集成策略的入口

  • 路由级渐进加载:路由天然是代码分割边界,适合按页面、次级面板、图表、评论区等粒度做懒加载与骨架屏。
  • 路由级模块装配:当系统变大后,路由经常成为子系统挂载、预加载、权限控制和微前端集成的边界。
  • 渐进式架构视角:React Router 的位置会延伸到 SPA、SSR、服务端重写、缓存策略和资源加载优先级之间的协同。

最小实践路径

  1. 先掌握 BrowserRouterRoutesRoute,理解路径如何映射页面组件。
  2. 再掌握 <Outlet />、嵌套路由、index 路由,理解路由树如何映射布局树。
  3. 再掌握 LinkNavLinkuseNavigate,区分 UI 导航与流程跳转。
  4. 再掌握 useParamsuseSearchParams、location state,区分资源身份、可分享状态与一次性上下文。
  5. 再理解 loaderactionerrorElement,把数据读取、提交和错误处理提升到路由层。
  6. 最后把路由放进懒加载、SSR、微前端和渐进式集成这些架构问题里看。

常见失误

  • BrowserRouter 部署后刷新 404:服务端没有把未知路径回退到入口 HTML。
  • 父路由写了 children,但父组件里忘了放 <Outlet />
  • 把筛选条件、分页、排序放在组件本地 state,导致链接无法分享、刷新无法恢复。
  • 嵌套路由和 UI 结构不一致,导致路由表越来越难维护。
  • 本来可以用 Link 表达的信息架构,被过度写成 useNavigate 事件逻辑。
  • 把数据请求全塞进组件 useEffect,导致页面进入后再瀑布式加载。

相关概念 / 下层卡片

相关入口

暂时结论

React Router 的核心学习路径是:先理解 URL 如何映射视图,再理解路由如何组织布局与加载,最后理解路由如何成为应用拆分和架构演进的入口。