React Router 极简指南(v6+)

这是一篇为你梳理的 React Router 核心知识文章,精简、到位、易懂,帮助你快速掌握 React 路由的用法。


前言

React Router 是 React 应用中最流行的路由库,它允许你在单页应用中实现多页面导航,保持 UI 与 URL 同步。当前主流版本是 v6,如果你还在用 v5,建议升级------v6 的 API 更简洁,思维模型也更清晰。

一、核心思想

一句话:根据 URL 的不同,渲染不同的组件。

React Router 将"路由"看作一个组件树,URL 变化时,它会匹配对应的 <Route>,然后把组件渲染到 <Outlet> 位置。

二、三个必须知道的组件

1. BrowserRouter

包裹整个应用,提供路由上下文。通常放在最外层:

jsx 复制代码
import { BrowserRouter } from 'react-router-dom';

root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

2. Routes 与 Route

Routes 是 v6 新增的容器,替代了 v5 的 Switch。Route 定义路径与组件的映射。

jsx 复制代码
import { Routes, Route } from 'react-router-dom';

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

要点:

  • 使用 element 属性(不再是 component)。
  • 匹配规则变为"最佳匹配",不再需要 exact。

声明式导航,替代 <a> 标签,避免整页刷新。

jsx 复制代码
import { Link, NavLink } from 'react-router-dom';

<Link to="/about">关于</Link>

// NavLink 可以知道当前是否激活,用于菜单高亮
<NavLink to="/about" className={({ isActive }) => isActive ? 'active' : ''}>
  关于
</NavLink>

三、嵌套路由与布局

v6 的嵌套路由不需要再写一大堆 /*,直接嵌套 <Route> 即可。父组件使用 <Outlet /> 来渲染子路由。

jsx 复制代码
// 定义路由
<Routes>
  <Route path="/dashboard" element={<Dashboard />}>
    <Route path="stats" element={<Stats />} />
    <Route path="settings" element={<Settings />} />
  </Route>
</Routes>

// Dashboard 组件
function Dashboard() {
  return (
    <div>
      <h1>控制台</h1>
      <nav>...</nav>
      <Outlet /> {/* 子路由的内容会显示在这里 */}
    </div>
  );
}

访问 /dashboard/stats 时,Dashboard 和 Stats 会一起渲染,完美实现布局复用。

四、动态路由与参数

用冒号 :id 定义动态段,在组件中通过 useParams 读取。

jsx 复制代码
<Route path="/users/:userId" element={<UserProfile />} />

// UserProfile 组件内
import { useParams } from 'react-router-dom';

function UserProfile() {
  const { userId } = useParams();
  // 根据 userId 请求数据...
}

五、编程式导航

不能用 <Link> 的场景(例如按钮点击后跳转),使用 useNavigate。

jsx 复制代码
import { useNavigate } from 'react-router-dom';

function LoginButton() {
  const navigate = useNavigate();
  const handleLogin = async () => {
    await loginApi();
    navigate('/dashboard'); // 普通跳转
    // navigate(-1); // 返回上一页
  };
  return <button onClick={handleLogin}>登录</button>;
}

六、查询参数(Query String)

v6 没有内置的 useQuery,推荐用浏览器原生的 URLSearchParams 来处理。

jsx 复制代码
import { useSearchParams } from 'react-router-dom';

function SearchPage() {
  const [searchParams, setSearchParams] = useSearchParams();
  const keyword = searchParams.get('q') || '';

  const updateKeyword = (newKeyword) => {
    setSearchParams({ q: newKeyword });
  };
  // ...
}

useSearchParams 的用法和 useState 类似,读写查询参数非常方便。

七、404 页面与索引路由

jsx 复制代码
<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/dashboard" element={<Dashboard />}>
    <Route index element={<DashboardHome />} /> {/* 访问 /dashboard 时显示 */}
    <Route path="stats" element={<Stats />} />
  </Route>
  <Route path="*" element={<NotFound />} /> {/* 必须放在最后 */}
</Routes>
  • index 路由:父路径精确匹配时渲染的默认子组件。
  • * 通配路由:捕获所有未匹配的路径,常用于 404 页面。

八、保护路由(权限控制)

可以封装一个 ProtectedRoute 组件,根据登录状态决定是渲染子组件还是重定向。

jsx 复制代码
function ProtectedRoute({ children }) {
  const isAuthenticated = useAuth(); // 自定义 Hook,返回用户登录状态
  const location = useLocation();

  if (!isAuthenticated) {
    // 把当前路径传给登录页,登录后可跳回
    return <Navigate to="/login" state={{ from: location }} replace />;
  }
  return children;
}

// 用法
<Route path="/dashboard" element={
  <ProtectedRoute>
    <Dashboard />
  </ProtectedRoute>
} />

九、v6 变化一览(对比 v5)

v5 v6
<Switch> <Routes>
component={Comp} element={<Comp />}
无序匹配 + exact 自动最佳匹配
嵌套需写完整路径或 useRouteMatch 直接相对路径嵌套 + <Outlet>
useHistory useNavigate
useRouteMatch 无,用相对路径和 useParams 等替代
类组件支持 全面拥抱 Hooks

十、最佳实践速记

  1. 路由集中定义:将所有路由放在一个配置文件中,清晰可维护。
  2. 懒加载组件 :结合 React.lazy() 和 Suspense 实现代码分割。
  3. 始终考虑 404 :加一条 path="*" 的路由。
  4. 导航高亮用 NavLink:比手动判断更简洁。
  5. 权限等逻辑抽象成 wrapper 组件:保持路由配置干净。

总结

React Router 的核心就这么简单。掌握以上内容,你就能应对 90% 的实际项目需求。当需要更高级特性(如数据加载、路由过渡动画)时,再去查阅官方文档,你会发现自己已经有扎实的底子去理解它们了。

相关推荐
麦麦麦当劳大王7 小时前
【油猴脚本】Boss直聘 岗位职责复制
开发语言·前端·javascript
小lu飞8 小时前
2026小红书小工具怎么制作:纯前端 ZIP 打包、沙箱限制与笔记挂载流程
前端·笔记·ai·ai编程
smallcelebration8 小时前
151 从0开始搭建后端项目
前端·firefox
wangruofeng8 小时前
手机和电脑传文件,除了微信还有 LocalSend
前端
excel9 小时前
基于 GPT 的自动发布文章接口方案:从一句话或一张图片生成并发布内容
前端·javascript·后端
其实防守也摸鱼10 小时前
个人学习 Pwn 思路:从基础到漏洞利用的进阶路径
大数据·前端·人工智能·chrome·算法·安全·网络安全
朱涛的自习室11 小时前
212 个需求、22 万行代码:Agent 接管开源项目的 19 天
android·前端·人工智能
aZhe的全栈知识分享11 小时前
AI 还原 Figma 效果总达不到预期?先别急着让它写代码
前端·后端·面试
review4454311 小时前
Codex Hooks 入门实战:生命周期事件、matcher 与5分钟跑通一个钩子
前端·agent·vibecoding
函数小陈11 小时前
阿里云部署DSH与RAM完成运维
前端·后端