react-router vs react-router-dom vs @reach/router vs react-router-native
React 路由生态核心包对比:架构、选型与迁移
react-routerreact-router-dom@reach/routerreact-router-native类似的npm包:

React 路由生态核心包对比:架构、选型与迁移

react-router 是 React 应用路由管理的核心库,提供了路由匹配和导航的基础逻辑。react-router-domreact-router-native 分别是针对 Web 浏览器环境和 React Native 移动环境的具体实现,它们依赖并扩展了核心包的功能。@reach/router 是早期的路由方案,现已合并至 react-router v6 并标记为废弃,不再建议在新项目中使用。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
react-router27,773,97056,3214.18 MB15625 天前MIT
react-router-dom24,114,70156,3215.46 kB15625 天前MIT
@reach/router441,0226,849-1736 年前MIT
react-router-native41,09456,32140.2 kB1562 个月前MIT

React 路由核心包深度对比:架构、选型与迁移

在 React 生态系统中,路由管理是构建单页应用(SPA)和移动应用的基石。react-router 系列包提供了从核心逻辑到环境适配的完整解决方案,但不同包之间的职责划分常常让开发者感到困惑。特别是随着 @reach/router 的合并与废弃,选型变得更加关键。本文将深入对比这四个包的技术细节,帮助你在架构设计中做出正确决策。

🏗️ 核心定位与依赖关系

理解这些包的关系是选型的第一步。它们不是平行关系,而是层级关系。

react-router 是核心库。

  • 包含所有路由钩子(如 useNavigate)和逻辑。
  • 不包含任何特定环境(浏览器或原生)的组件。
  • 通常作为其他包的依赖自动安装,不建议直接用于应用层。
// react-router: 核心钩子
import { useLocation, useNavigate } from 'react-router';
// 仅包含逻辑,无 BrowserRouter 等环境组件

react-router-dom 是 Web 环境实现。

  • 依赖 react-router
  • 增加了 BrowserRouterHashRouterLink 等 DOM 特定组件。
  • Web 项目的实际入口包。
// react-router-dom: Web 环境
import { BrowserRouter, Link } from 'react-router-dom';
// 包含核心功能 + 浏览器历史 API 封装

react-router-native 是移动端环境实现。

  • 依赖 react-router
  • 增加了 NativeRouterLink 等 React Native 特定组件。
  • 移动项目的实际入口包。
// react-router-native: 原生环境
import { NativeRouter, Link } from 'react-router-native';
// 包含核心功能 + 原生导航栈封装

@reach/router 是历史遗留包。

  • 曾是 react-router 的竞争者,后合并入 v6。
  • 现已废弃,API 风格与 v6 类似但不再维护。
  • 仅存在于旧项目中。
// @reach/router: 已废弃 (Legacy)
import { Router, Link } from '@reach/router';
// 不再接收更新,存在潜在兼容性风险

🌍 环境适配:Web 与 原生

路由的核心是监听地址变化并渲染组件,但 Web 和 Native 的地址管理机制完全不同。

react-router-dom 使用浏览器历史 API。

  • 基于 window.history 实现导航。
  • 支持 BrowserRouter (HTML5 History) 和 HashRouter
  • 处理浏览器的后退、前进按钮。
// react-router-dom: 浏览器历史
import { BrowserRouter, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
      </Routes>
    </BrowserRouter>
  );
}

react-router-native 使用原生导航栈。

  • 基于 React Native 的导航容器。
  • 不支持浏览器历史,而是管理原生视图栈。
  • 处理物理返回键和手势导航。
// react-router-native: 原生栈
import { NativeRouter, Routes, Route } from 'react-router-native';

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

react-router 不处理环境细节。

  • 仅提供 RoutesRoute 等通用组件。
  • 必须配合上述环境包使用,否则无法监听地址变化。
// react-router: 通用组件 (需配合环境包)
import { Routes, Route } from 'react-router';
// 单独使用无法工作,缺少历史监听器

@reach/router 使用自有历史实现。

  • 曾试图简化 API,但造成了生态分裂。
  • 合并后,其历史实现已被 react-router v6 取代。
// @reach/router: 旧版实现
import { Router } from '@reach/router';
// 旧版 API,不再兼容新生态工具

🔗 导航组件与 API 差异

在实际编码中,链接和编程式导航是最常用的功能。不同包的实现细节直接影响代码迁移成本。

react-router-dom 提供标准 Link 组件。

  • 渲染为 <a> 标签,支持 SEO 和右键打开新标签。
  • 编程式导航使用 useNavigate 钩子。
// react-router-dom: Web 链接
import { Link, useNavigate } from 'react-router-dom';

function Nav() {
  const navigate = useNavigate();
  return (
    <>
      <Link to="/about">About</Link>
      <button onClick={() => navigate('/home')}>Go Home</button>
    </>
  );
}

react-router-native 提供原生 Link 组件。

  • 渲染为 TouchableOpacity 或其他原生触摸组件。
  • 编程式导航同样使用 useNavigate,但行为适配原生栈。
// react-router-native: 原生链接
import { Link, useNavigate } from 'react-router-native';

function Nav() {
  const navigate = useNavigate();
  return (
    <>
      <Link to="/about">About</Link>
      <button onPress={() => navigate('/home')}>Go Home</button>
    </>
  );
}

react-router 仅提供钩子。

  • 不包含 Link 组件,因为不知道如何渲染链接。
  • 仅导出 useNavigate 等逻辑钩子。
// react-router: 仅逻辑
import { useNavigate } from 'react-router';
// 无 Link 组件,需自行实现或依赖环境包

@reach/router 使用旧版 API。

  • 使用 navigate 函数而非钩子。
  • Link 组件 API 类似,但底层实现不同。
// @reach/router: 旧版导航
import { Link, navigate } from '@reach/router';

function Nav() {
  return (
    <>
      <Link to="/about">About</Link>
      <button onClick={() => navigate('/home')}>Go Home</button>
    </>
  );
}

⚠️ 废弃警告与迁移路径

@reach/router 的状态是架构决策中的关键风险点。

@reach/router 已正式废弃。

  • 官方明确建议迁移至 react-router v6。
  • 不再修复 Bug 或支持新 React 版本。
  • 继续使用会导致技术债务积累。
// ❌ 不推荐:旧项目代码
import { Router } from '@reach/router';

// ✅ 推荐:迁移后代码
import { BrowserRouter } from 'react-router-dom';

迁移核心变化。

  • Router 替换为 BrowserRouterNativeRouter
  • navigate 函数替换为 useNavigate 钩子。
  • 路径匹配逻辑基本兼容,但需检查通配符语法。
// 迁移对比
// 旧:@reach/router
<Route path="users/:id" component={User} />

// 新:react-router-dom v6
<Route path="users/:id" element={<User />} />

📊 总结对比表

特性react-routerreact-router-domreact-router-native@reach/router
定位核心逻辑层Web 环境实现原生环境实现已废弃的旧方案
适用平台任意 (需自定义)浏览器 (Web)iOS / Android (React Native)旧 Web 项目
路由组件Routes, RouteBrowserRouter, HashRouterNativeRouterRouter
导航组件Link, NavLinkLinkLink
导航钩子useNavigate, useLocation同左 (继承)同左 (继承)navigate 函数
维护状态✅ 活跃维护✅ 活跃维护✅ 活跃维护❌ 已废弃

💡 架构师建议

react-router-dom 是 Web 开发的标准答案。 除非你有极其特殊的自定义需求,否则不要直接使用 react-router 核心包。react-router-dom 提供了所有必要的功能,且与 React 生态工具链集成最好。对于新项目,它是唯一推荐的选择。

react-router-native 是移动开发的必经之路。 在 React Native 中,不要尝试复用 Web 的路由组件。原生导航栈的行为(如手势返回、动画)与 Web 历史完全不同。使用专用包能确保用户体验符合平台规范。

彻底告别 @reach/router 如果你正在维护旧项目,制定迁移计划是当务之急。react-router v6 已经吸收了 Reach Router 的优点,继续分离维护没有意义。迁移成本可控,但长期收益巨大。

最终结论:Web 选 react-router-dom,移动端选 react-router-native,核心包 react-router 仅作为依赖存在,@reach/router 请立即停用。

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

  • react-router:

    仅在你需要构建自定义路由环境或非标准平台适配时使用。对于绝大多数 Web 或移动端应用,应直接选择 react-router-domreact-router-native,因为它们包含了核心包的所有功能并添加了环境必要的组件。

  • react-router-dom:

    这是构建 Web 应用的标准选择。如果你正在开发运行在浏览器中的 React 网站、单页应用(SPA)或混合应用,此包提供了 BrowserRouterLink 等必要的 DOM 操作组件,是大多数前端项目的默认选项。

  • @reach/router:

    不要在新项目中使用此包。它已正式废弃,功能已合并到 react-router v6 中。继续使用将面临缺乏维护和安全更新的风险,建议立即迁移到 react-router-dom

  • react-router-native:

    专用于 React Native 移动应用开发。如果你需要为 iOS 或 Android 构建原生界面,此包提供了 NativeRouter 和适配触摸导航的 Link 组件,能正确处理原生栈导航行为。

react-router的README

react-router is the primary package in the React Router project.

Installation

npm i react-router