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. RoutesRoute

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

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 时,DashboardStats 会一起渲染,完美实现布局复用。

四、动态路由与参数

用冒号 :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% 的实际项目需求。当需要更高级特性(如数据加载、路由过渡动画)时,再去查阅官方文档,你会发现自己已经有扎实的底子去理解它们了。

相关推荐
林恒smileZAZ1 小时前
CSS 滚动驱动动画(scroll-timeline):无 JS 实现滚动特效
前端·javascript·css
俺不会敲代码啊啊啊1 小时前
el-table实现行拖拽(包含展开项)
前端·vue.js·typescript
明月_清风1 小时前
从 AST 视角看透前端工程化:一条编译管线如何串联起所有工具
前端
架构源启1 小时前
2026 进阶篇:Spring Boot响应式编程 + Spring AI 1.1.4 流式实战 + Vue前端完整实现(避坑指南)
java·前端·vue.js·人工智能·spring boot·spring·ai编程
白开水都有人用1 小时前
前端 AES 加密 + 后端解密 + MD5 校验登录
前端
OpenTiny社区2 小时前
还在手写 AI 聊天页?这款 Vue3 气泡组件,直接搞定流式对话!
前端·vue.js·ai编程
毛骗导演2 小时前
Cladue Code 源码解析-键盘事件与 Vim 模式:parse-keypress 解析状态机
前端·架构
渐儿2 小时前
GLB 模型压缩 — 完整流程与代码映射
前端
疯狂成瘾者2 小时前
Prompt分层策略
前端·数据库·prompt