react-router 是平台无关的核心路由逻辑库,提供路由匹配、钩子和基础组件,适用于 React Native、SSR 及跨平台场景。react-router-dom 是基于前者为 Web 浏览器环境提供的具体实现,增加了 BrowserRouter、Link 等 DOM 特定组件。两者共同构成了 React 生态的标准路由解决方案,但在适用环境和 API 暴露上存在明确分工。
react-router 和 react-router-dom 是 React 生态中最核心的路由解决方案,但它们服务于不同的层级。react-router 提供平台无关的核心路由逻辑,而 react-router-dom 则是在此基础上为 Web 浏览器环境封装的具体实现。理解两者的界限对于构建可维护、跨平台的应用架构至关重要。
react-router-dom 提供了专为浏览器设计的路由提供者。
BrowserRouter 利用 HTML5 History API。HashRouter 利用 URL 哈希值。// react-router-dom: 浏览器环境
import { BrowserRouter } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>...</Routes>
</BrowserRouter>
);
}
react-router 提供通用的路由提供者,不依赖浏览器 API。
MemoryRouter 将历史记录的堆栈保存在内存中。// react-router: 通用/非浏览器环境
import { MemoryRouter } from 'react-router';
function App() {
return (
<MemoryRouter initialEntries={['/home']}>
<Routes>...</Routes>
</MemoryRouter>
);
}
react-router-dom 提供了声明式的导航组件。
<Link> 渲染为 <a> 标签,支持右键打开新标签。<NavLink> 支持激活状态的样式处理。// react-router-dom: 声明式导航
import { Link } from 'react-router-dom';
function Nav() {
return <Link to="/about">关于我们</Link>;
}
react-router 不包含 DOM 组件,依赖钩子进行命令式导航。
<Link> 组件。useNavigate 钩子触发跳转。// react-router: 命令式导航
import { useNavigate } from 'react-router';
function Nav() {
const navigate = useNavigate();
return <button onClick={() => navigate('/about')}>关于我们</button>;
}
react-router-dom 支持读取浏览器特有的查询参数。
useSearchParams 钩子。?key=value 部分。// react-router-dom: 查询参数
import { useSearchParams } from 'react-router-dom';
function Search() {
const [params, setParams] = useSearchParams();
const q = params.get('query');
return <div>{q}</div>;
}
react-router 提供通用的位置信息访问。
useLocation 钩子。pathname, search, hash, state。search 字符串。// react-router: 位置状态
import { useLocation } from 'react-router';
function Search() {
const location = useLocation();
// 需要手动解析 location.search
return <div>{location.pathname}</div>;
}
尽管存在环境差异,两者在核心路由定义上完全一致。
<Routes> 和 <Route> 组件。// 两者通用:路由定义
import { Routes, Route } from 'react-router'; // 或 react-router-dom
function App() {
return (
<Routes>
<Route path="/user/:id" element={<User />} />
</Routes>
);
}
useParams, useNavigate, useOutlet 在两者中均可用。react-router-dom 重新导出了 react-router 的所有核心钩子。// 两者通用:获取参数
import { useParams } from 'react-router'; // 或 react-router-dom
function User() {
const { id } = useParams();
return <div>{id}</div>;
}
useNavigate 的行为在两者中保持一致。replace, state 等选项。// 两者通用:跳转逻辑
import { useNavigate } from 'react-router'; // 或 react-router-dom
function Submit() {
const navigate = useNavigate();
const handleSubmit = () => navigate('/success', { replace: true });
return <button onClick={handleSubmit}>提交</button>;
}
| 特性 | react-router | react-router-dom |
|---|---|---|
| 定位 | 核心逻辑层 (Platform Agnostic) | Web 绑定层 (DOM Specific) |
| 路由提供者 | MemoryRouter, Router | BrowserRouter, HashRouter |
| 导航组件 | 无 (需自定义) | <Link>, <NavLink> |
| 查询参数 | 手动解析 location.search | useSearchParams 钩子 |
| 适用环境 | React Native, SSR, 测试 | 浏览器 Web 应用 |
| 依赖关系 | 无依赖 | 依赖 react-router |
react-router-dom 是 Web 开发的标准选择 🌐。
如果你的目标是构建运行在浏览器中的 React 单页应用,请直接使用 react-router-dom。它提供了所有必要的浏览器集成(如历史管理、链接组件、搜索参数),并且内部已经包含了 react-router 的所有功能。不要为了“纯粹性”而刻意导入 react-router,这会增加不必要的复杂度。
react-router 是跨平台与底层架构的基石 🧱。
如果你正在开发 React Native 应用(配合 react-router-native),或者需要在 Node.js 服务端进行路由匹配,亦或是编写一套需要在 Web 和 Native 之间共享的路由逻辑库,那么你需要直接依赖 react-router。它让你摆脱对 DOM API 的依赖,实现真正的逻辑复用。
最终建议:在 95% 的 Web 项目中,import { ... } from 'react-router-dom' 是最佳实践。仅在构建底层库或非 Web 平台时,才考虑直接使用 react-router。
选择 react-router 如果你正在开发 React Native 应用,或者需要编写一套在 Web 和 Native 之间共享的通用路由逻辑库。它也适用于需要在 Node.js 服务端进行路由匹配或进行单元测试的场景,因为它不依赖浏览器 DOM API。
选择 react-router-dom 如果你正在构建标准的浏览器 Web 应用。它是绝大多数前端项目的首选,因为它封装了 HTML5 History API,提供了 <Link> 等语义化组件,并且内部已经重新导出了 react-router 的所有核心功能,无需额外安装核心库。
react-router is the primary package in the React Router project.
npm i react-router