React Router 完全指南:核心概念、动态路由与实战技巧

17 阅读2分钟

React Router 是 React 生态中最流行的客户端路由库,用于构建单页应用(SPA)中的导航和路由系统。它允许你在不刷新页面的情况下动态切换视图,保持 UI 与 URL 同步。以下是 React Router 的核心概念:


1. 核心包

  • react-router-dom:用于 Web 应用(基于 react-router,增加了浏览器专用的 API)。
  • react-router-native:用于 React Native 应用。

2. 核心组件

<BrowserRouter><HashRouter>

  • 作用:为应用提供路由上下文(包裹整个应用)。
    • BrowserRouter:使用 HTML5 History API(pushState/popState),URL 如 /home
    • HashRouter:使用 URL 的 hash 部分(#),兼容旧浏览器,URL 如 /#/home

<Routes><Route>

  • <Routes>:包裹一组 <Route>,负责匹配当前 URL 并渲染对应的组件。
  • <Route>:定义路径和组件的映射关系。
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
    </Routes>
    

<Link><NavLink>

  • <Link>:导航链接,取代 <a> 标签,避免页面刷新。
    <Link to="/about">About</Link>
    
  • <NavLink>:特殊的 <Link>,可添加激活状态的样式(如高亮)。
    <NavLink to="/about" style={({ isActive }) => ({ color: isActive ? 'red' : 'blue' })}>
      About
    </NavLink>
    

<Outlet>

  • 作用:在嵌套路由中渲染子路由的组件(类似插槽)。
    function Dashboard() {
      return (
        <div>
          <h1>Dashboard</h1>
          <Outlet /> {/* 子路由的组件会渲染在这里 */}
        </div>
      );
    }
    

<Navigate>

  • 作用:重定向到其他路径。
    <Route path="/old" element={<Navigate to="/new" />} />
    

3. 动态路由与参数

URL 参数

  • 通过 :param 定义动态路径,用 useParams() 获取参数:
    <Route path="/users/:id" element={<UserProfile />} />
    
    // 在组件中获取参数
    function UserProfile() {
      const { id } = useParams();
      return <div>User ID: {id}</div>;
    }
    

查询参数(Search Params)

  • 使用 useSearchParams() 获取和修改 URL 查询字符串(如 ?name=John):
    function Search() {
      const [searchParams, setSearchParams] = useSearchParams();
      const keyword = searchParams.get("keyword");
      return <input defaultValue={keyword} />;
    }
    

4. 嵌套路由

  • 通过父路由的 <Outlet> 渲染子路由:
    <Route path="/dashboard" element={<Dashboard />}>
      <Route path="stats" element={<Stats />} />  // 匹配 /dashboard/stats
      <Route path="settings" element={<Settings />} />
    </Route>
    

5. 编程式导航

  • 使用 useNavigate() 钩子实现 JS 跳转:
    function Login() {
      const navigate = useNavigate();
      const handleLogin = () => {
        navigate("/dashboard", { replace: true, state: { user: "Alice" } });
      };
      return <button onClick={handleLogin}>Login</button>;
    }
    
    • replace: true 替换历史记录(不留下后退记录)。
    • state 传递隐式数据(可通过 useLocation() 读取)。

6. 其他 API

  • useLocation():获取当前 URL 信息(路径、hash、state 等)。
  • useRouteError()(v6.4+):捕获路由错误(配合 errorElement 使用)。

7. 数据路由(v6.4+)

React Router 6.4 引入了基于数据加载的 API(类似 Remix 风格):

  • createBrowserRouter + routerProvider:通过配置对象定义路由和加载器。
  • loader/action:在路由渲染前异步加载数据或处理表单提交。
const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    loader: () => fetch("/api/data"), // 异步加载数据
    children: [
      { path: "team", element: <Team /> },
    ],
  },
]);

// 在根组件中使用 <RouterProvider router={router} />

总结

React Router 的核心是声明式路由动态匹配,通过组件化方式管理导航和状态。V6 版本简化了 API,并强化了嵌套路由和数据加载能力,适合构建现代 SPA 应用。