路由(React-Router)

如果你是在学习前端开发,React-Router 是 React 应用中最常用的路由管理库,用于实现单页面应用(SPA)的页面切换,而不需要浏览器刷新。

目前主流版本是:


一、什么是路由

传统网站:

复制代码
https://xxx.com/login
https://xxx.com/user
https://xxx.com/order

每访问一个页面,浏览器都会向服务器重新请求页面。

React SPA:

复制代码
https://xxx.com/login
https://xxx.com/user
https://xxx.com/order

URL变化了,但实际上只有一个 HTML 页面。

React Router 根据 URL 显示不同组件。

例如:

复制代码
/login -> Login组件
/user -> User组件
/order -> Order组件

二、安装

React Router v7:

复制代码
npm install react-router

或者:

复制代码
yarn add react-router

三、基础使用

1. 创建页面

Login.jsx

复制代码
export default function Login() {
  return <h1>登录页</h1>;
}

Home.jsx

复制代码
export default function Home() {
  return <h1>首页</h1>;
}

2. 配置路由

main.jsx

复制代码
import React from "react";
import ReactDOM from "react-dom/client";
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router";

import Home from "./pages/Home";
import Login from "./pages/Login";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Home />,
  },
  {
    path: "/login",
    element: <Login />,
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <RouterProvider router={router} />
);

四、路由跳转

类似HTML中的a标签

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

function App() {
  return (
    <>
      <Link to="/">首页</Link>

      <Link to="/login">
        登录
      </Link>
    </>
  );
}

效果:

复制代码
首页
登录

点击不会刷新页面。


五、编程式导航

useNavigate

跳转

复制代码
import { useNavigate } from "react-router";

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

  return (
    <button
      onClick={() => navigate("/home")}
    >
      登录
    </button>
  );
}

返回上一页

复制代码
navigate(-1);

前进一页

复制代码
navigate(1);

六、嵌套路由

项目中最常用。

例如后台管理系统:

复制代码
/
 ├─ 首页
 ├─ 用户管理
 ├─ 订单管理

路由配置

复制代码
const router = createBrowserRouter([
  {
    path: "/",
    element: <Layout />,
    children: [
      {
        index: true,
        element: <Home />,
      },
      {
        path: "user",
        element: <User />,
      },
      {
        path: "order",
        element: <Order />,
      },
    ],
  },
]);

Layout组件

复制代码
import { Outlet } from "react-router";

function Layout() {
  return (
    <>
      <h1>后台系统</h1>

      <Outlet />
    </>
  );
}

Outlet

相当于:

复制代码
<router-view />

用于显示子路由。


七、动态路由

路由配置

复制代码
{
  path: "/user/:id",
  element: <User />
}

获取参数

复制代码
import { useParams } from "react-router";

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

  return <h1>{id}</h1>;
}

访问:

复制代码
/user/1001

输出:

复制代码
1001

八、Query参数

URL

复制代码
/user?id=1001

获取

复制代码
import { useSearchParams } from "react-router";

function User() {
  const [params] =
    useSearchParams();

  console.log(
    params.get("id")
  );
}

结果:

复制代码
1001

九、路由守卫(权限控制)

React Router 没有像 Vue 那样的全局守卫。

通常封装组件:

复制代码
function AuthRoute({ children }) {
  const token =
    localStorage.getItem("token");

  if (!token) {
    return <Navigate to="/login" />;
  }

  return children;
}

使用:

复制代码
{
  path: "/user",
  element: (
    <AuthRoute>
      <User />
    </AuthRoute>
  )
}

十、404页面

复制代码
{
  path: "*",
  element: <NotFound />
}

十一、懒加载

大型项目必用。

User.jsx

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

const User = lazy(
  () => import("./User")
);

路由

复制代码
{
  path: "/user",
  element: (
    <Suspense fallback={<div>Loading...</div>}>
      <User />
    </Suspense>
  )
}