react-router-dom vs wouter vs @reach/router vs react-router-native
React 应用路由库选型指南
react-router-domwouter@reach/routerreact-router-native类似的npm包:
React 应用路由库选型指南

@reach/routerreact-router-domreact-router-nativewouter 都是用于 React 应用的路由解决方案,但针对不同平台和场景。react-router-dom 是面向 Web 的主流路由库,功能全面且活跃维护;react-router-native 专为 React Native 移动应用设计;wouter 是一个极简的 Web 路由替代方案,强调轻量和无依赖;而 @reach/router 已被官方废弃,不应在新项目中使用。这些库共同解决了组件与 URL 路径的映射、导航、参数传递等核心路由需求,但在 API 设计、平台适配和功能深度上存在显著差异。

npm下载趋势
3 年
GitHub Stars 排名
统计详情
npm包名称
下载量
Stars
大小
Issues
发布时间
License
react-router-dom17,665,95256,1065.46 kB1404 天前MIT
wouter889,6747,70174.8 kB2424 天前Unlicense
@reach/router387,7846,863-1736 年前MIT
react-router-native19,07656,10639.9 kB14010 个月前MIT

React 路由方案深度对比:@reach/router、react-router-dom、react-router-native 与 wouter

在现代 React 应用中,路由是不可或缺的核心功能。面对多个可选方案,开发者需要根据项目规模、平台目标、性能要求和维护状态做出合理选择。本文将从真实工程视角出发,深入比较 @reach/routerreact-router-domreact-router-nativewouter 四个主流路由库的技术细节、适用场景和关键差异。

⚠️ 维护状态警示

首先必须明确:@reach/router 已被官方标记为废弃(deprecated)。根据其 npm 页面 和 GitHub 仓库说明,该库不再接受新功能或重大修复,且其核心作者已将其合并到 react-router v6 中。因此,任何新项目都不应再使用 @reach/router。本文仍将其纳入比较,仅用于帮助维护旧代码的团队理解其定位。

🧭 核心用途与平台支持

这四个包虽然都解决“路由”问题,但目标平台和抽象层级不同:

  • react-router-dom:专为 Web 浏览器环境 设计,基于 HTML5 History API,是 React 官方推荐的 Web 路由方案。
  • react-router-native:专为 React Native 移动应用 设计,使用原生导航栈(如 iOS 的 UINavigationController),不适用于 Web。
  • wouter:极简的 Web 路由库,无依赖,API 精简,适合对 bundle size 敏感或追求轻量化的项目。
  • @reach/router(已废弃):曾是轻量级 Web 路由替代方案,强调无障碍(a11y)和简洁 API,现已停止维护。

💡 关键区分:react-router-domwouter 用于 Web;react-router-native 用于 React Native;三者不可混用。

🔌 基础路由定义与匹配

react-router-dom(v6+)

使用声明式 <Route> 组件嵌套定义路由,路径匹配基于 嵌套路由(nested routes) 模型。

// react-router-dom
import { BrowserRouter, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/users/:id" element={<User />} />
        <Route path="/settings" element={<Settings />} />
      </Routes>
    </BrowserRouter>
  );
}

react-router-native

API 与 react-router-dom 高度一致,但底层使用 React Native 的导航组件(需配合 react-navigation 或类似库)。

// react-router-native
import { NativeRouter, Routes, Route } from 'react-router-native';

function App() {
  return (
    <NativeRouter>
      <Routes>
        <Route path="/" element={<HomeScreen />} />
        <Route path="/profile" element={<ProfileScreen />} />
      </Routes>
    </NativeRouter>
  );
}

wouter

采用 Hook 驱动 的极简设计,无需顶层 Provider,直接在组件内使用 useLocation<Route>

// wouter
import { Router, Route, Link } from 'wouter';

function App() {
  return (
    <Router>
      <Route path="/" component={Home} />
      <Route path="/users/:id" component={User} />
    </Router>
  );
}

// 或使用 Hook
function UserPage() {
  const [match] = useRoute("/users/:id");
  if (!match) return null;
  return <div>User ID: {match.params.id}</div>;
}

@reach/router(已废弃)

曾以 自动嵌套无障碍跳转 为特色,路径作为组件 prop 传入。

// @reach/router (deprecated)
import { Router, Link } from '@reach/router';

function App() {
  return (
    <Router>
      <Home path="/" />
      <User path="/users/:id" />
    </Router>
  );
}

📦 动态参数与查询处理

参数提取

  • react-router-dom:通过 useParams() Hook 获取路径参数。
// react-router-dom
import { useParams } from 'react-router-dom';

function User() {
  const { id } = useParams();
  return <div>User {id}</div>;
}
  • wouter:通过 useParams()useRoute() 返回的 params 对象获取。
// wouter
import { useParams } from 'wouter';

function User() {
  const params = useParams();
  return <div>User {params.id}</div>;
}
  • react-router-native:同样使用 useParams(),行为与 Web 版一致。

  • @reach/router:参数直接作为 props 传入组件。

// @reach/router
function User({ id }) {
  return <div>User {id}</div>;
}

查询字符串处理

  • react-router-dom:需手动解析 window.location.search 或使用 useSearchParams()(v6.4+)。
// react-router-dom
import { useSearchParams } from 'react-router-dom';

function Search() {
  const [searchParams] = useSearchParams();
  const q = searchParams.get('q');
  return <div>Query: {q}</div>;
}
  • wouter:不内置查询解析,需自行处理或使用第三方工具。

  • react-router-native:通常不涉及查询字符串(移动端多用深层链接参数)。

🔄 导航与编程式跳转

声明式导航(Link)

所有 Web 方案均提供 <Link> 组件:

// react-router-dom
<Link to="/users/123">Go to User</Link>

// wouter
<Link href="/users/123">Go to User</Link>

// @reach/router
<Link to="/users/123">Go to User</Link>

注意:wouter 使用 href 而非 to,更贴近原生 <a> 标签。

编程式导航

  • react-router-dom:使用 useNavigate() Hook。
const navigate = useNavigate();
navigate('/users/123');
  • wouter:使用 useLocation() 返回的 setter 函数。
const [, setLocation] = useLocation();
setLocation('/users/123');
  • react-router-native:同样使用 useNavigate(),但底层触发原生导航动画。

  • @reach/router:使用 navigate() 工具函数。

import { navigate } from '@reach/router';
navigate('/users/123');

📱 平台适配与集成

  • Web vs Nativereact-router-domwouter 仅适用于浏览器环境,依赖 window.historyreact-router-native 专为 React Native 构建,无法在 Web 使用。试图跨平台混用会导致运行时错误。

  • React Native 生态react-router-native 通常需与 react-navigation 等原生导航库协同工作,而 react-router-dom 在 Web 中可独立运行。

  • 无障碍支持@reach/router 曾以出色的 a11y 支持著称(如自动管理焦点),这一特性已被吸收进 react-router v6 的 <Link> 实现中。

🧩 高级功能对比

嵌套路由与布局

  • react-router-dom:通过嵌套 <Route> 实现共享布局。
<Route path="/dashboard" element={<DashboardLayout />}>
  <Route index element={<Overview />} />
  <Route path="settings" element={<Settings />} />
</Route>
  • wouter:需手动组合组件,无内置嵌套路由支持。

  • @reach/router:自动基于组件树嵌套匹配路径(已废弃)。

数据加载与加载状态

  • react-router-dom(v6.4+):支持 LoadersActions,实现数据预加载和表单提交。
<Route
  path="/users/:id"
  loader={async ({ params }) => fetchUser(params.id)}
  element={<User />}
/>
  • 其他方案:均无内置数据加载机制,需自行集成 SWR、React Query 或 useEffect。

自定义历史对象

  • react-router-dom:可通过 <Router> 组件注入自定义 history(如内存 history 用于测试)。

  • wouter:支持自定义 history 适配器,但需额外配置。

  • react-router-native:使用原生导航历史,不可替换。

🛠️ 如何选择?实战建议

新 Web 项目

  • 若需 完整路由生态(嵌套、loader、error boundary、SEO 支持)→ 选 react-router-dom
  • 若追求 极致轻量(<3KB)、简单路由需求、或微前端子应用 → 选 wouter
  • 绝对不要 选择 @reach/router(已废弃)。

React Native 项目

  • 必须使用 react-router-native,但需注意其与原生导航库的集成复杂度。

迁移场景

  • @reach/router 迁移:官方推荐升级至 react-router-dom v6,大部分概念(如动态参数、无障碍)已继承。

📊 总结对比表

特性react-router-domreact-router-nativewouter@reach/router (废弃)
平台WebReact NativeWebWeb
Bundle Size较大(功能完整)中等极小(~2KB)小(已停止维护)
嵌套路由✅ 声明式嵌套❌ 需手动实现✅ 自动嵌套
数据加载✅ Loaders/Actions (v6.4+)
无障碍支持✅ 内置依赖原生✅(曾是亮点)
自定义 History✅(需适配器)
维护状态✅ 活跃✅ 活跃✅ 活跃❌ 已废弃

💡 最终建议

  • Web 项目首选 react-router-dom:它是 React 路由的事实标准,功能全面、文档完善、社区支持强大,适合绝大多数应用场景。
  • 轻量级 Web 应用考虑 wouter:如果你的路由逻辑简单(如单页应用、静态站点),且对 bundle size 极度敏感,wouter 是一个优雅的替代方案。
  • React Native 项目用 react-router-native:尽管生态不如 Web 成熟,但它是官方提供的跨平台路由抽象。
  • 彻底避开 @reach/router:已有项目应制定迁移计划至 react-router-dom v6+。

路由虽小,却关乎整个应用的架构根基。选择时务必结合平台、功能需求和长期维护性综合判断 —— 别让一时的轻量诱惑,换来未来的迁移成本。

如何选择: react-router-dom vs wouter vs @reach/router vs react-router-native
  • react-router-dom:

    选择 react-router-dom 如果你正在构建一个功能完整的 Web 应用,需要嵌套路由、数据加载(Loaders/Actions)、无障碍支持、SEO 友好性以及强大的社区生态。它是 React Web 路由的事实标准,适合中大型项目和长期维护的产品。

  • wouter:

    选择 wouter 如果你构建的是轻量级 Web 应用(如静态站点、微前端子应用或演示原型),对 bundle size 极度敏感,且路由需求简单(基本路径匹配和跳转)。它无外部依赖、API 简洁,但缺乏高级功能如嵌套路由和内置数据加载。

  • @reach/router:

    不要在新项目中使用 @reach/router,因为它已被官方标记为废弃,不再接收功能更新或重大修复。如果你正在维护一个使用它的旧项目,应计划迁移到 react-router-dom v6 或更高版本,以获得持续的安全更新和新功能支持。

  • react-router-native:

    选择 react-router-native 如果你正在开发 React Native 移动应用,并希望使用与 Web 版 react-router 相似的声明式路由 API。它专为原生平台设计,能与 React Native 的导航系统集成,但需注意其功能集相比 Web 版较为有限。

react-router-dom的README

This package simply re-exports everything from react-router to smooth the upgrade path for v6 applications. Once upgraded you can change all of your imports and remove it from your dependencies:

-import { Routes } from "react-router-dom"
+import { Routes } from "react-router"