【前端】【React】第四章:深入理解 React Router 及前端路由管理

十一、React Router 及前端路由管理

React 是一个单页面应用(SPA)框架,通常使用 React Router 进行路由管理。React Router 提供 客户端路由,避免页面刷新,提高用户体验。


(一)React Router 基本概念

React Router 采用 基于组件的路由,核心概念包括:

术语 作用
BrowserRouter 使应用支持 HTML5 History API 的路由
Routes 用于包裹所有 Route 组件
Route 定义 URL 与组件的映射关系
Link / NavLink 生成前端导航链接
useNavigate 编程式导航,替代 history.push
useParams 获取 URL 动态参数
useLocation 获取当前 URL 信息

(二)安装 React Router

sh 复制代码
npm install react-router-dom

(三)基本路由配置

1. 创建路由
jsx 复制代码
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./Home";
import About from "./About";

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

export default App;
2. 创建 HomeAbout 组件
jsx 复制代码
function Home() {
  return <h1>首页</h1>;
}

function About() {
  return <h1>关于我们</h1>;
}

jsx 复制代码
import { Link } from "react-router-dom";

function Navbar() {
  return (
    <nav>
      <Link to="/">首页</Link>
      <Link to="/about">关于我们</Link>
    </nav>
  );
}
jsx 复制代码
import { NavLink } from "react-router-dom";

function Navbar() {
  return (
    <nav>
      <NavLink to="/" style={({ isActive }) => ({ color: isActive ? "red" : "black" })}>
        首页
      </NavLink>
      <NavLink to="/about">关于我们</NavLink>
    </nav>
  );
}

(五)动态路由与参数 useParams

1. 定义动态路由
jsx 复制代码
<Routes>
  <Route path="/user/:id" element={<User />} />
</Routes>
2. 获取路由参数
jsx 复制代码
import { useParams } from "react-router-dom";

function User() {
  const { id } = useParams();
  return <h1>用户 ID: {id}</h1>;
}

(六)编程式导航 useNavigate

1. 跳转到指定页面
jsx 复制代码
import { useNavigate } from "react-router-dom";

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

  return (
    <div>
      <h1>首页</h1>
      <button onClick={() => navigate("/about")}>跳转到关于页</button>
    </div>
  );
}
2. 传递参数
jsx 复制代码
navigate("/user/123");

(七)获取当前路由 useLocation

jsx 复制代码
import { useLocation } from "react-router-dom";

function CurrentRoute() {
  const location = useLocation();
  return <h1>当前路径: {location.pathname}</h1>;
}

(八)嵌套路由(子路由)

1. 定义子路由
jsx 复制代码
<Routes>
  <Route path="/dashboard" element={<Dashboard />}>
    <Route path="profile" element={<Profile />} />
    <Route path="settings" element={<Settings />} />
  </Route>
</Routes>
2. Dashboard 组件中渲染子组件
jsx 复制代码
import { Outlet } from "react-router-dom";

function Dashboard() {
  return (
    <div>
      <h1>仪表盘</h1>
      <Outlet />
    </div>
  );
}

(九)路由重定向

jsx 复制代码
import { Navigate } from "react-router-dom";

function NotFound() {
  return <Navigate to="/" />;
}

(十)路由守卫(权限控制)

1. 创建 ProtectedRoute 组件
jsx 复制代码
import { Navigate } from "react-router-dom";

function ProtectedRoute({ isAuth, children }) {
  return isAuth ? children : <Navigate to="/login" />;
}
2. 使用路由守卫
jsx 复制代码
<Route path="/dashboard" element={<ProtectedRoute isAuth={isLoggedIn}><Dashboard /></ProtectedRoute>} />

十二、总结

1. React Router 核心概念

术语 作用
Routes / Route 定义路由
Link / NavLink 导航链接
useNavigate 编程式跳转
useParams 获取动态参数
useLocation 获取当前 URL
Navigate 进行路由重定向
Outlet 处理嵌套路由

2. 路由功能

  • 基本路由<Route path="/" element={<Home />} />
  • 动态路由<Route path="/user/:id" element={<User />} />
  • 导航链接<Link to="/about">关于我们</Link>
  • 编程式导航navigate("/dashboard")
  • 嵌套路由<Outlet />
  • 路由重定向<Navigate to="/" />
  • 路由守卫 :封装 <ProtectedRoute> 组件

在大型 React 应用中,单独维护路由表 是一种更好的实践,可以提高可读性、可维护性和复用性。通常,开发者会在 routes.jsrouter/index.js 文件中集中管理路由。


(一)使用独立路由表

1. 创建 routes.js

jsx 复制代码
// routes.js
import Home from "./pages/Home";
import About from "./pages/About";
import Dashboard from "./pages/Dashboard";
import Profile from "./pages/Profile";
import Settings from "./pages/Settings";
import NotFound from "./pages/NotFound";

const routes = [
  { path: "/", element: <Home /> },
  { path: "/about", element: <About /> },
  {
    path: "/dashboard",
    element: <Dashboard />,
    children: [
      { path: "profile", element: <Profile /> },
      { path: "settings", element: <Settings /> },
    ],
  },
  { path: "*", element: <NotFound /> },
];

export default routes;

2. App.js 里引入并渲染

jsx 复制代码
// App.js
import { BrowserRouter, Routes, Route } from "react-router-dom";
import routes from "./routes";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        {routes.map(({ path, element, children }) => (
          <Route key={path} path={path} element={element}>
            {children &&
              children.map((child) => (
                <Route key={child.path} path={child.path} element={child.element} />
              ))}
          </Route>
        ))}
      </Routes>
    </BrowserRouter>
  );
}

export default App;

(二)改进:使用 lazySuspense 进行按需加载

当页面较多时,可以使用 React.lazy 进行 按需加载(懒加载),减少首屏加载时间。

1. 修改 routes.js

jsx 复制代码
import { lazy } from "react";

const Home = lazy(() => import("./pages/Home"));
const About = lazy(() => import("./pages/About"));
const Dashboard = lazy(() => import("./pages/Dashboard"));
const Profile = lazy(() => import("./pages/Profile"));
const Settings = lazy(() => import("./pages/Settings"));
const NotFound = lazy(() => import("./pages/NotFound"));

const routes = [
  { path: "/", element: <Home /> },
  { path: "/about", element: <About /> },
  {
    path: "/dashboard",
    element: <Dashboard />,
    children: [
      { path: "profile", element: <Profile /> },
      { path: "settings", element: <Settings /> },
    ],
  },
  { path: "*", element: <NotFound /> },
];

export default routes;

2. App.js 里添加 Suspense

jsx 复制代码
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { Suspense } from "react";
import routes from "./routes";

function App() {
  return (
    <BrowserRouter>
      <Suspense fallback={<div>加载中...</div>}>
        <Routes>
          {routes.map(({ path, element, children }) => (
            <Route key={path} path={path} element={element}>
              {children &&
                children.map((child) => (
                  <Route key={child.path} path={child.path} element={child.element} />
                ))}
            </Route>
          ))}
        </Routes>
      </Suspense>
    </BrowserRouter>
  );
}

export default App;

(三)结合路由守卫

routes.js 里可以添加 权限控制 ,通过 meta.auth 判断是否需要登录:

1. 修改 routes.js

jsx 复制代码
import { lazy } from "react";
import ProtectedRoute from "./components/ProtectedRoute";

const Home = lazy(() => import("./pages/Home"));
const About = lazy(() => import("./pages/About"));
const Dashboard = lazy(() => import("./pages/Dashboard"));
const Login = lazy(() => import("./pages/Login"));

const routes = [
  { path: "/", element: <Home /> },
  { path: "/about", element: <About /> },
  {
    path: "/dashboard",
    element: <ProtectedRoute><Dashboard /></ProtectedRoute>,
    meta: { auth: true }, // 需要登录
  },
  { path: "/login", element: <Login /> },
];

export default routes;

2. 创建 ProtectedRoute.js

jsx 复制代码
import { Navigate } from "react-router-dom";

function ProtectedRoute({ children }) {
  const isLoggedIn = localStorage.getItem("token"); // 模拟鉴权
  return isLoggedIn ? children : <Navigate to="/login" />;
}

export default ProtectedRoute;

总结

单独维护路由表 ,更易管理

支持嵌套路由 ,减少重复代码

支持懒加载 ,优化性能

支持路由守卫,可控访问权限

👉 这样可以让路由更加清晰、解耦,提高可维护性! 🚀

下一章:React 状态管理(Context API、Redux、Zustand) 🚀

相关推荐
崔庆才丨静觅11 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606112 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了12 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅12 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅12 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅13 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment13 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅13 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊13 小时前
jwt介绍
前端
爱敲代码的小鱼13 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax