React - Router 6.x 版本使用

React Router 6.0 :https://reactrouter.com/en/main/start/overview

一. 对比 ReactRouter 5.x 版本

  1. 包大小的不同 V5 大小在20.8k左右,压缩后在7.3k左右;V6 大小在10.8k左右,压缩后在3.8k左右
  2. 内置组件的变化:移除<Switch/> ,新增 <Routes/>等。
  3. 语法的变化:component={About} 变为 element={<About/>}等。
  4. 新增多个hook:useParamsuseNavigateuseMatch等。
  5. 官方明确推荐使用函数式组件了。

二. Router 安装

yarn add react-router-dom@6.4.5

npm install react-router-dom@6.4.5

三. Component

1. 路由模式 BrowserRouter 和 HashRouter

6.x版本中<HashRouter><BrowserRouter> 的用法与 5.x 相同。

https://blog.csdn.net/Jie_1997/article/details/126740893

2. Routes 与 Route

  1. v6 版本中移除了先前的<Switch>,引入了新的替代者:<Routes>
  2. <Routes><Route>要配合使用,且必须要用<Routes>包裹<Route>
  3. <Route> 相当于一个 if 语句,如果其路径与当前 URL 匹配,则呈现其对应的组件。
  4. <Route caseSensitive> 属性用于指定:匹配时是否区分大小写(默认为 false)。
  5. 当URL发生变化时,<Routes> 都会查看其所有子 <Route> 元素以找到最佳匹配并呈现组件 。
  6. <Route> 也可以嵌套使用,且可配合useRoutes()配置 “路由表” ,但需要通过 <Outlet> 组件来渲染其子路由。
<Routes>
  {/* path属性用于定义路径,element属性用于定义当前路径所对应的组件 */}
  <Route path="/login" element={<Login />}></Route>
  {/* 用于定义嵌套路由,home是一级路由,对应的路径/home */}
  <Route path="home" element={<Home />}>
    {/* page1 和 page2 是二级路由,对应的路径是/home/page1 或 /home/page2 */}
    <Route path="page1" element={<Page1 />}></Route>
    <Route path="page2" element={<Page2 />}></Route>
  </Route>
  {/* 
    Route也可以不写element属性, 表示用于展示嵌套的路由
    ./user 对应的路径是/users/user
    /user 对应根路径/user
    user 与./user意思相同,对应根路径/users/user
  */}
  <Route path="users">
    <Route path="user" element={<User />} />
  </Route>
</Routes>

3. Link

  1. 用于修改URL,且不发送网络请求(路由链接)。
  2. 使用时,外侧需要用<BrowserRouter><HashRouter>包裹。
import React from 'react'

export default function Demo() {
  return (
    <div>
      <Link to="/路径">按钮</Link>
    </div>
  )
}

4. NavLink

  1. <Link>组件类似,且可实现导航的“高亮”效果
  2. NavLink 默认类名是 active
  3. NavLink上添加了end属性后,若路由的子组件匹配成功,则路由的导航没有高亮效果。
{/* 自定义类名 */}
<NavLink
  to="login"
  className={({ isActive }) => {
    console.log(isActive);
    return isActive ? "class1" : "class2";
  }}
>
  login
</NavLink>
{/* 若Home的子组件匹配成功,则Home的导航没有高亮效果 */}
<NavLink to="home" end >home</NavLink>

5. Navigate

  1. 只要<Navigate>组件被渲染,就会修改路径,切换视图
  2. replace属性用于控制跳转模式(push 或 replace,默认是push)
import React, { useState } from "react";
import { Navigate } from "react-router-dom";

export default function Home() {
  const [count, setCount] = useState(1);
  return (
    <div>
      <h3>Home组件</h3>
      {/* 根据count的值决定是否切换视图 */}
      {count === 1 ? (
        <h4>count的值为{count}</h4>
      ) : (
        <Navigate to="/about" replace={true} />
      )}
      {/* 修改count值 */}
      <button onClick={() => setCount(2)}>修改count值为2</button>
    </div>
  );
}

6. Outlet

<Route>产生路由嵌套时,渲染其对应的后续子路由。

import React from "react";
import { NavLink, Outlet } from "react-router-dom";

export default function Home() {
  return (
    <div>
      <h2>Home组件内容</h2>
      <div>
        {/* 子路由 */}
        <ul>
          <li>
            <NavLink replace to="page1">page1</NavLink>
          </li>
          <li>
            <NavLink to="page2">page2</NavLink>
          </li>
        </ul>
        {/* 指定子路由组件呈现的位置 */}
        <Outlet />
      </div>
    </div>
  );
}

四. Hooks

1. useRoutes() —— 路由表

根据路由表,动态创建<Routes><Route>

  1. src 文件夹下创建 routes 文件夹,用于存放路由文件
  2. src/routes 文件夹下创建 index.js 文件,用于配置路由
    //路由表配置:src/routes/index.js
    import About from "../pages/About";
    import Home from "../pages/Home";
    import { Navigate } from "react-router-dom";
    
    export default [
      {
        path: "/about",
        element: <About />,
      },
      {
        path: "/home",
        element: <Home />,
      },
      {
        path: "/",
        element: <Navigate to="/about" />,
      },
    ];
    
  3. src/App.js 文件中引入使用
    import React from "react";
    import { NavLink, useRoutes } from "react-router-dom";
    import routes from "./routes";
    
    export default function App() {
      //根据路由表生成对应的路由规则
      const element = useRoutes(routes);
      return (
        <div className="app">
          <div className="menu">
            {/* 路由链接 */}
            <NavLink to="/about">About</NavLink>
            <NavLink to="/home">Home</NavLink>
          </div>
          <div className="body">
            {/* 路由组件 */}
            {element}
          </div>
        </div>
      );
    }
    
  4. src/index.js 文件中使用 <BrowserRouter></BrowserRouter> 包裹 <App />
    import React from "react";
    import ReactDOM from "react-dom/client";
    import App from "./App";
    import reportWebVitals from "./reportWebVitals";
    import { BrowserRouter } from "react-router-dom/dist";
    
    const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(
      <BrowserRouter>
        <App />
      </BrowserRouter>
    );
    reportWebVitals();
    

2. 路由传参

传递参数id,参数值为001

2.1 useParams() —— params传参

  • 路由设置
    // 路由表形式
    {
      path: "detail/:id",
      element: <Detail />,
    },
    
    // 标签形式
    <Routes>
      <Route path="detail/:id" element={<Detail />} />
    </Routes>
    
  • 路由链接传参
    <Link to={`detail/001`}>传参</Link>
    
  • 接收参数
    import React from "react";
    import { useParams } from "react-router-dom";
    
    export default function Detail() {
      // 接收参数
      const { id, title, content } = useParams();
      return <div>Detail</div>;
    }
    

2.2 useSearchParams() —— search传参(query传参)

  • 路由设置
    // 路由表形式
    {
      path: "detail",
      element: <Detail />,
    },
    
    // 标签形式
    <Routes>
      <Route path="detail" element={<Detail />} />
    </Routes>
    
  • 路由链接传参
    <Link to={`detail?id=001`}>传参</Link>
    
  • 接收参数
    import React from "react";
    import { useSearchParams } from "react-router-dom";
    
    export default function Detail() {
      // 返回一个包含两个值的数组,内容分别为:当前的seaech参数、更新search的函数
      const [search, setSearch] = useSearchParams();
      // 取出对应参数
      const id = search.get("id");
    
      return <div>Detail</div>;
    }
    

2.3 useLocation() —— state传参

  • 路由设置
    // 路由表形式
    {
      path: "detail",
      element: <Detail />,
    },
    
    // 标签形式
    <Routes>
      <Route path="detail" element={<Detail />} />
    </Routes>
    
  • 路由链接传参
    <Link
      to="detail"
      state={{
        id: "001",
      }}
    >
      传参
    </Link>
    
  • 接收参数
    import React from "react";
    import { useLocation } from "react-router-dom";
    
    export default function Detail() {
      // 接收参数
      const { state } = useLocation();
      return <div>Detail</div>;
    }
    

3. useNavigate() —— 编程式路由导航

  1. 指定具体的路径
    import React from "react";
    import { useNavigate } from "react-router-dom";
    
    export default function Demo() {
      const navigate = useNavigate();
      const handle = () => {
        navigate(
          "detail", //指定路径
          {
            replace: false, //是否为 replace 模式
            state: {
              id: "001", //state 传参
            },
          }
        );
      };
      return (
        <div>
          <button onClick={handle}>跳转</button>
        </div>
      );
    }
    
  2. 传入数值,前进或后退
    import React from "react";
    import { useNavigate } from "react-router-dom";
    
    export default function Demo() {
      const navigate = useNavigate();
      const handle = () => {
        navigate(-1);
        // navigate(1); //前进
      };
      return (
        <div>
          <button onClick={handle}>后退</button>
        </div>
      );
    }
    

4. useInRouterContext() —— 判断组件是否在 Router的上下文中呈现

如果组件在 <Router> 的上下文中呈现,则 useInRouterContext 钩子返回 true,否则返回 false

import React from "react";
import { useInRouterContext } from "react-router-dom";

export default function Demo() {
  // 打印判断
  console.log(useInRouterContext());
  return <div>Demo</div>;
}

5. useNavigationType() —— 返回当前的导航类型

  1. 返回当前的导航类型(用户是如何来到当前页面的)
  2. 返回值:POPPUSHREPLACE
  3. POP是指在浏览器中直接打开了这个路由组件(刷新页面)
import React from "react";
import { useNavigationType } from "react-router-dom";

export default function Dome() {
  // 打印查看
  console.log(useNavigationType());
  return <div>Dome</div>;
}

6. useOutlet() —— 呈现当前组件中渲染的嵌套路由

import React from "react";
import { NavLink, Outlet, useOutlet } from "react-router-dom";

export default function Home() {
  /**
   * useOutlet()	当前组件中渲染的嵌套路由
   * 如果嵌套路由没有挂载,则result为null
   * 如果嵌套路由已经挂载,则展示嵌套的路由对象
   */
  console.log(useOutlet());
  return (
    <div>
      <h2>Home组件内容</h2>
      <div>
        {/* 子路由 */}
        <ul>
          <li>
            <NavLink replace to="page1">page1</NavLink>
          </li>
          <li>
            <NavLink to="page2">page2</NavLink>
          </li>
        </ul>
        {/* 指定子路由组件呈现的位置 */}
        <Outlet />
      </div>
    </div>
  );
}

7. useResolvedPath() —— 解析URL值

import React from "react";
import { useResolvedPath } from "react-router-dom";

export default function Demo() {
  // 解析其中的:path、search、hash值
  console.log(useResolvedPath("/user?id=001&name=tom#qwe"));
  return <div>Demo</div>;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值