Skip to content

React Router:前端路由、嵌套路由与导航组织

React 里只会写组件还不够。

一旦应用变成多页面结构,你很快就会碰到这些问题:

  1. URL 和页面视图怎么对应
  2. 页面切换时,哪些组件该保留,哪些该切换
  3. 权限页面怎么拦
  4. 嵌套路由怎么组织布局和子页面

这篇文章重点讲:

  1. React Router 到底解决什么问题
  2. 为什么它不是简单“页面跳转工具”
  3. 声明式路由、嵌套路由和导航怎么理解
  4. 路由守卫思路和工程边界是什么

1. React Router 为什么会出现

单页应用不是每次点链接都让浏览器整页刷新。

这就需要一层机制来回答:

  1. 当前 URL 是什么
  2. 当前 URL 对应哪个页面组件
  3. 页面切换时,哪一层布局继续保留
  4. 导航前后要不要做校验和跳转控制

React Router 解决的就是这条主线。

🌟 React Router 不是“跳转插件”,而是 把 URL、页面结构和导航行为组织起来的路由系统。


2. 最小路由配置长什么样

jsx
import { BrowserRouter, Routes, Route } from "react-router-dom";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/orders" element={<OrderPage />} />
        <Route path="/users/:id" element={<UserDetailPage />} />
      </Routes>
    </BrowserRouter>
  );
}

这里最关键的事情是:

  1. BrowserRouter 负责浏览器历史记录模式
  2. Routes 负责在一组路由里匹配当前地址
  3. Route 负责声明“哪个 path 对应哪个页面”

3. 声明式路由在解决什么问题

React Router 非常强调声明式。

它的核心价值是,页面结构和 URL 映射关系被清楚地写在一处,而不是到处手写 if-else 跳转。

例如:

jsx
<Route path="/products" element={<ProductListPage />} />
<Route path="/products/:id" element={<ProductDetailPage />} />

这段配置本身就在表达:

  1. 列表页路径是什么
  2. 详情页路径是什么
  3. 参数从哪里来

4. 路由参数怎么理解

像这样的路径:

text
/users/:id

里的 :id 表示动态参数。

在组件里可以这样拿:

jsx
import { useParams } from "react-router-dom";

function UserDetailPage() {
  const { id } = useParams();

  return <div>user id: {id}</div>;
}

它最适合解决的是,同一种页面结构下,根据 URL 参数决定当前展示哪一份数据。


5. 嵌套路由为什么很重要

真实应用里,很多页面不是“每跳一次就整页全换”。

更常见的是:

  1. 顶部导航保留
  2. 侧边栏保留
  3. 只有内容区切换

这时嵌套路由就很自然。

jsx
import { BrowserRouter, Outlet, Route, Routes } from "react-router-dom";

function DashboardLayout() {
  return (
    <div className="dashboard-layout">
      <aside>menu</aside>
      <main>
        <Outlet />
      </main>
    </div>
  );
}

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/dashboard" element={<DashboardLayout />}>
          <Route path="orders" element={<OrderPage />} />
          <Route path="users" element={<UserPage />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

这里的 Outlet 最重要的作用是,给当前匹配到的子路由页面留一个插入位置。


6. 导航怎么做

jsx
import { Link } from "react-router-dom";

function Menu() {
  return <Link to="/orders">订单页</Link>;
}

适合普通页面跳转。

6.2 编程式导航:useNavigate

jsx
import { useNavigate } from "react-router-dom";

function LoginPage() {
  const navigate = useNavigate();

  const handleSuccess = () => {
    navigate("/dashboard");
  };

  return <button onClick={handleSuccess}>登录成功后跳首页</button>;
}

适合:

  1. 登录后跳转
  2. 提交成功后跳转
  3. 权限校验后重定向

7. 路由守卫思路怎么理解

React Router 没有像某些框架那样直接给你一个“全局守卫 API”去套一切。

但工程上很常见的思路是:

  1. 用包装路由组件做权限校验
  2. 没权限就重定向

例如:

jsx
import { Navigate } from "react-router-dom";

function RequireAuth({ isLogin, children }) {
  if (!isLogin) {
    return <Navigate to="/login" replace />;
  }

  return children;
}

然后:

jsx
<Route
  path="/dashboard"
  element={
    <RequireAuth isLogin={isLogin}>
      <DashboardPage />
    </RequireAuth>
  }
/>

这条思路的本质是,把“能不能进入这个页面”也变成组件树的一部分。


8. React Router 在应用结构里真正重要的是什么

很多人只把它理解成:

  1. 地址栏变化
  2. 页面跳转

但真实项目里它更重要的是这些:

  1. 页面层级怎么组织
  2. 布局层和内容层怎么拆
  3. URL 是否能表达当前页面状态
  4. 是否便于权限和导航控制

也就是说,路由不只是“导航”,也是应用信息架构的一部分。


9. React Router 最常见的误区

9.1 以为路由只是地址跳转

它更深一层是在组织页面结构。

9.2 所有页面都平铺在一层

真实项目里很多布局明显应该用嵌套路由表达。

9.3 权限控制全写在页面内部

很多时候更清晰的做法是先在路由层做入口拦截。


10. 一句话总结

React Router 的核心价值,是把 URL、页面视图、布局层级和导航控制组织成一套声明式路由系统,让单页应用不只是“能切页面”,而是“有稳定的信息架构和导航边界”。

基于 VitePress 构建的个人技术笔记。