React Router
React 生态中最广泛使用的声明式路由库,提供组件化的路由配置与导航能力。
React Router 是 React 生态中最成熟的路由方案,v7 融合 Remix 设计理念,提供 Loader/Action 数据加载、嵌套路由、文件路由约定和完整 SSR 支持,npm 周下载量超 1000 万次。
React Router
React 生态中最广泛使用的声明式路由库,提供组件化的路由配置与导航能力。
技术简介说明
React Router 是 React 生态中最成熟、使用最广泛的路由解决方案。自 2014 年由 Ryan Florence 和 Michael Jackson 创建以来,它已经从简单的路由库发展为完整的应用框架。React Router 的核心理念是"一切皆组件",通过声明式的 JSX 标签来定义路由规则,使路由配置与 React 组件树无缝融合。
React Router v6/v7 带来了革命性的架构变化,引入了数据加载 API(loader/action 模式)、嵌套路由、并行数据加载等现代特性。v7 版本(2024年底发布)更是直接对标 Remix 框架,将其设计理念融入 React Router,使其从单纯的路由库进化为全栈应用框架。v7 同时提供了兼容 v6 的"基础模式"和全新的"框架模式"两种选择,降低了迁移成本。
作为 React 社区的事实标准路由方案,React Router 拥有庞大的用户基础、丰富的学习资源和活跃的社区生态。npm 周下载量超过 1000 万次,是构建 React SPA 和全栈应用的首选路由方案。
基本信息
- 官网:https://reactrouter.com/
- GitHub:https://github.com/remix-run/react-router
- License:MIT
- 最新版本:v7.6.3(2025年5月)
- 主要维护者/公司:Shopify(收购 Remix 后接管)、Brooks Lybrand、Michael Jackson、Ryan Florence
快速上手
安装
# npm
npm install react-router
# pnpm
pnpm add react-router
# yarn
yarn add react-router
# 注意:React Router v7 的包名从 react-router-dom 改为 react-router
# v7 不再需要单独安装 react-router-dom 和 history基础配置
React Router v7 提供两种使用模式:
基础模式(兼容 v6): 使用 createBrowserRouter API,适合已有项目迁移。
import { createBrowserRouter, RouterProvider } from 'react-router'
const router = createBrowserRouter([
{
path: '/',
element: <Home />,
},
{
path: '/about',
element: <About />,
},
])
function App() {
return <RouterProvider router={router} />
}框架模式(推荐): 使用文件约定式路由,类似 Remix。
# 使用官方脚手架创建
npx create-react-router@latest my-app最小示例
// v7 基础模式
import { createBrowserRouter, RouterProvider, Link } from 'react-router'
function Root() {
return (
<div>
<nav>
<Link to="/">首页</Link>
<Link to="/about">关于</Link>
</nav>
<Outlet />
</div>
)
}
function Home() {
return <h1>首页</h1>
}
function About() {
return <h1>关于</h1>
}
const router = createBrowserRouter([
{
path: '/',
element: <Root />,
children: [
{ index: true, element: <Home /> },
{ path: 'about', element: <About /> },
],
},
])
export default function App() {
return <RouterProvider router={router} />
}核心概念与架构
路由配置对象
React Router v7 使用基于对象的路由配置(不再支持 JSX 声明式 <Routes>),每个路由节点包含 path、element、loader、action、children 等字段。
数据加载模型(Loader/Action)
v7 引入了 Remix 风格的数据加载:
- Loader:路由组件的数据获取函数,在渲染前执行,支持并行加载
- Action:表单提交的数据变更函数,处理 POST/PUT/DELETE 请求
- 数据通过
useLoaderData()和useActionData()传递给组件
嵌套路由与布局路由
路由支持嵌套结构,父路由的 element 通过 <Outlet /> 渲染子路由。布局路由没有 path 属性,用于共享布局。
导航与链接
<Link>:声明式导航组件<NavLink>:带激活状态的导航,支持className回调useNavigate():编程式导航useSubmit():表单提交 hook
路由匹配与参数
- 支持动态参数
:id、可选参数:id?、通配符* useParams()获取路由参数useLocation()获取当前 locationuseSearchParams()获取/设置 URL 查询参数
错误边界
路由级别错误处理,通过 errorElement 定义错误组件,useRouteError() 获取错误信息。
代码分割
支持 lazy() 函数实现路由级别的代码分割和按需加载。
核心特性
- 声明式路由:基于对象配置的路由定义,结构清晰
- 数据加载 API(Loader/Action):服务端渲染友好的数据获取模式,消除瀑布流请求
- 嵌套路由:天然支持 URL 与组件树的映射关系
- 并行数据加载:多个路由的 loader 并行执行,减少加载时间
- 表单处理:内置
<Form>组件和 action 处理,增强渐进式表单提交 - 代码分割:通过
lazy()实现路由级别的按需加载 - 错误边界:路由级别的错误隔离,防止全局崩溃
- 服务端渲染(SSR):原生支持 SSR,框架模式提供完整的 SSR 方案
- 类型安全:v7 增强了 TypeScript 支持,泛型类型参数
- 渐进增强:框架模式支持 JavaScript 关闭时的降级体验
- 向后兼容:提供 v6 兼容模式,平滑迁移路径
生态图
关键依赖
- React ≥ 18:核心框架依赖
- @remix-run/router:底层路由引擎(从 Remix 合并而来)
- Turbo:v7 框架模式的构建工具
相关插件与扩展
- react-router-typesafe:增强类型安全的路由参数验证
- connected-react-router(v5 时代):Redux 状态同步(v7 已不推荐)
- @remix-run/react:Remix 框架已合并入 React Router v7
社区生态
- remix-utils:Remix/React Router 实用工具集
- react-router-scroll-behavior:滚动位置管理
- useRoutes 封装库:多个第三方路由辅助工具
- 大量 UI 框架提供 React Router 集成(MUI、Ant Design、shadcn/ui)
开发工具
- React Router DevTools:浏览器扩展,路由状态可视化
- create-react-router:官方脚手架工具
适用场景
- 单页应用(SPA):React Router 是构建 React SPA 的首选方案,提供完整的客户端路由能力
- 全栈应用:v7 框架模式支持 SSR、数据加载、表单处理,适合构建全栈 Web 应用
- 企业级应用:嵌套路由、代码分割、错误边界等特性满足大型应用需求
- 多页面应用(MPA)增强:在传统多页面应用中嵌入 SPA 体验
- 电商/内容平台:SEO 友好的 SSR 支持和数据加载优化
- 后台管理系统:路由鉴权、权限控制、动态路由配置
开发与工程化
开发流程
# 创建新项目(框架模式)
npx create-react-router@latest my-app
# 开发
cd my-app && npm run dev
# 构建
npm run build
# 生产部署
npm start项目结构(框架模式)
app/
├── routes/ # 路由目录
│ ├── _index.tsx # 根路由
│ ├── about.tsx # /about 路由
│ └── users.$id.tsx # 动态路由 /users/:id
├── root.tsx # 根布局
└── entry.client.tsx # 客户端入口
CI/CD 集成
- 支持部署到 Node.js、Cloudflare Workers/Pages、Vercel、Netlify 等平台
react-router.config.ts配置部署目标适配器- Docker 部署使用标准 Node.js 构建流程
测试
# 使用 Vitest + @testing-library/react
npm install -D vitest @testing-library/react @testing-library/domimport { render, screen } from '@testing-library/react'
import { createMemoryRouter, RouterProvider } from 'react-router'
test('renders home route', () => {
const router = createMemoryRouter([{ path: '/', element: <Home /> }])
render(<RouterProvider router={router} />)
expect(screen.getByText('首页')).toBeInTheDocument()
})性能与安全
性能特点
- 并行数据加载:多个路由 loader 并行执行,显著减少首屏加载时间
- 预加载:
<Link prefetch>支持预加载路由数据和模块 - 代码分割:
lazy()函数实现路由级按需加载 - 流式渲染:框架模式支持 React Suspense 流式 SSR
优化建议
- 合理使用代码分割,避免单个路由包过大
- 利用
prefetch预加载频繁访问的路由 - 在 loader 中实现数据缓存和去重
- 使用
React.memo和useMemo优化组件渲染
安全注意事项
- XSS 防护:避免在路由参数中直接渲染用户输入,React 默认转义但需注意
dangerouslySetInnerHTML - 路由鉴权:在 loader 或 action 中验证用户权限,不要仅依赖前端路由隐藏
- CSRF 防护:action 中使用框架内置的 CSRF token 验证
- 敏感数据:loader 在服务端执行时可安全访问敏感数据,不要暴露到客户端
已知性能瓶颈
- 大型路由表(500+ 路由)的匹配性能
- 频繁的 location 变化可能导致不必要的重渲染
useLocation在深层组件中使用可能引起性能问题
技术对比
| 特性 | React Router v7 | TanStack Router | Wouter | Reach Router |
|---|---|---|---|---|
| 包体积 | ~45KB gzipped | ~30KB gzipped | ~2KB gzipped | ~8KB gzipped |
| 类型安全 | 中等(泛型支持) | 强(完整类型推导) | 弱 | 弱 |
| 数据加载 | 内置 Loader/Action | 内置 loader | 无 | 无 |
| SSR 支持 | 完整支持 | 支持 | 需手动实现 | 有限支持 |
| 嵌套路由 | 支持 | 支持 | 不支持 | 支持 |
| 代码分割 | lazy() 支持 | 支持 | 需手动实现 | 支持 |
| 文件路由约定 | v7 框架模式支持 | 通过插件支持 | 不支持 | 不支持 |
| 框架无关 | 否(React 专属) | 否(React 专属) | 否(React 专属) | 否(React 专属) |
| 学习曲线 | 中等 | 较陡 | 极低 | 低 |
| 社区生态 | 最丰富 | 快速增长 | 小型社区 | 已停止维护 |
| 状态管理 | 内置 form/navigation | 内置 search params | 无 | 无 |
| 维护状态 | 活跃(Shopify) | 活跃(Tanner Linsley) | 活跃(小型维护) | 已归档 |
最佳实践
路由组织
// ✅ 推荐:按功能模块组织路由
const router = createBrowserRouter([
{
path: '/',
element: <RootLayout />,
children: [
{ index: true, element: <Home /> },
{
path: 'dashboard',
lazy: () => import('./routes/dashboard'),
// dashboard/index.tsx 导出 { Component, loader, action }
},
{
path: 'settings',
lazy: () => import('./routes/settings'),
},
],
},
])数据加载
// ✅ 推荐:在 loader 中处理数据获取和错误
export async function loader({ params }: LoaderFunctionArgs) {
const user = await fetchUser(params.id)
if (!user) {
throw new Response('Not Found', { status: 404 })
}
return { user }
}
// ✅ 推荐:使用 defer 处理非关键数据
import { defer } from 'react-router'
export async function loader({ params }: LoaderFunctionArgs) {
const critical = await fetchCriticalData(params.id)
const secondary = fetchSecondaryData(params.id) // 不 await
return defer({ critical, secondary })
}鉴权模式
// ✅ 推荐:在 loader 中验证权限
export async function loader({ request }: LoaderFunctionArgs) {
const user = await getUser(request)
if (!user) {
throw redirect('/login')
}
return { user }
}
// ✅ 推荐:使用路由守卫组件
function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { user } = useLoaderData()
if (!user) return <Navigate to="/login" />
return children
}常见陷阱
- ❌ 不要在组件中使用
useEffect获取路由数据,使用loader - ❌ 不要在路由
element中直接执行业务逻辑 - ❌ 避免在
NavLink的className回调中执行高开销计算
技术局限与边界
已知限制
- React 专属:不支持 Vue、Svelte 等其他框架
- 包体积:相比 Wouter 等轻量方案,v7 包体积较大
- 框架模式锁定:框架模式与 Remix 深度耦合,迁移成本较高
- 非文件路由:基础模式不支持文件约定式路由(v7 框架模式除外)
不适用场景
- 非 React 项目(Vue、Svelte、Angular 等)
- 对包体积极度敏感的场景(< 5KB 需求)
- 简单的静态页面(无路由需求的单页面)
- React Native(需使用 Expo Router 或 React Navigation)
迁移注意事项
- v6 → v7:包名变更(
react-router-dom→react-router),API 大部分兼容 - v5 → v6/7:需要重构路由配置,
Switch→Routes,useHistory→useNavigate - Remix → React Router v7:Remix 已合并入 v7,直接升级即可
学习资源
- 官方文档:https://reactrouter.com/
- API 参考:https://api.reactrouter.com/
- GitHub 仓库:https://github.com/remix-run/react-router
- 教程:
- 社区资源:
- Reactiflux Discord 的 #react-router 频道
- GitHub Discussions
- Stack Overflow #react-router
- 视频:
2026 年现状
最新版本
React Router v7.6.x 是当前稳定版本(2025年5月),持续迭代中。
发展趋势
- Remix 合并完成:Remix 的核心团队(Brooks Lybrand 等)已加入 Shopify,Remix 的设计哲学完全融入 React Router v7
- Shopify 支持:Shopify 将 React Router 作为其 Hydrogen 框架的路由基础,投入更多资源
- 框架模式推广:官方积极推动框架模式作为新项目的首选,但基础模式仍长期维护
- 类型安全增强:社区反馈推动 TypeScript 类型推导的持续改进
社区活跃度
- GitHub Stars:~55k
- npm 周下载量:~1000万+
- 贡献者:700+
- 更新频率:每周发布补丁/次版本更新
未来路线图
- 持续的 TypeScript 类型改进
- 框架模式的功能完善和生态建设
- 更好的开发工具(DevTools 增强)
- 更多部署平台适配器
- v7 的长期稳定性维护,暂无 v8 计划