手把手教你React-Router6【万字详细长文】

注:本教程基于尚硅谷react-router-dom6教程。本教程使用react18。

概述

React-Router 是一个可以帮助开发者在 React 应用中实现路由功能的第三方库。它提供了一组 API 和组件来管理应用程序的 URL 和页面切换。使用 React-Router,可以将每个页面的路由路径与组件关联起来,当用户访问特定的 URL 时,渲染相应的组件。

React-Router 的 API 包括以下几个主要的组件:

  • BrowserRouter:使用 HTML5 history API,在应用程序中提供基于浏览器的导航。
  • HashRouter:使用散列值(hash)在应用程序中提供客户端路由。
  • Route:渲染与指定 URL 匹配的组件。
  • Switch:渲染第一个与当前 URL 匹配的 Route 或 Redirect。
  • Link:生成带有指定 URL 的锚标记()以导航到不同的路由。

除了这些主要组件之外,React-Router 还提供了其他一些有用的组件和 API,如 Redirect、withRouter 和 useHistory 等。

React-Router 有以下几个库:

  1. react-router:React Router 的核心库,提供基础功能,如 Route、Link、history 等。
  2. react-router-dom:是针对 Web 应用的库,提供了 BrowserRouter、HashRouter 等路由组件。
  3. react-router-native:是针对移动端应用的库,提供了 NativeRouter、MemoryRouter 等路由组件。
  4. react-router-config:提供了静态路由配置的能力,并且可以在服务端使用。
  5. react-router-redux:将 React-Router 和 Redux 集成,可以将路由状态同步到 Redux Store 中。

前端开发中,我们主要关注react-router-dom


React-Router的基础用法

项目搭建

我们使用react-ceate-app搭建一个基础的react项目,然后安环react-router-dom

npm i react-router-dom

创建如下结构目录

├─ package.json
├─ public
│  ├─ bootstrap.css
│  ├─ favicon.ico
│  └─ index.html
├─ README.md
├─ src
│  ├─ App.jsx
│  ├─ index.js
│  └─ pages
│     ├─ About.jsx
│     └─ Home.jsx

样式不是我们本教程的重点,因此直接使用了bootstrap.css中定义的一些样式。如果你需要这个文件,请从云盘下载


链接: pan.baidu.com/s/1OPY3aYsK… 提取码: a2fq

注意,需要在index.html中引入bootstrp的样式

react-router-dom引入

入口文件index.js

import React from "react";
import ReactDOM from "react-dom/client";
// 导入 BrowserRouter 组件
import { BrowserRouter } from "react-router-dom";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

BrowserRouter 是 React Router 库提供的一种路由组件,它使用 HTML5 中的 history API 来实现路由的跳转,并支持浏览器的前进后退等操作。

在 React 应用中使用 BrowserRouter 可以方便地实现页面的路由跳转和组件的渲染。使用时,需要将一个组件树放在一个 中,然后在组件中来设置路由跳转和组件渲染的规则。

路由导航设置NavLink和Link

代码及效果

App.jsx

import React from "react";
import { NavLink, Routes, Route } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";
export default function App() {
  return (
    <div>
      <div className="row">
        <div className="col-xs-offset-2 col-xs-8">
          <div className="page-header">
            <h2>React Router Demo</h2>
          </div>
        </div>
      </div>
      <div className="row">
        <div className="col-xs-2 col-xs-offset-2">
          <div className="list-group">
            {/* 路由链接 */}
            <NavLink className="list-group-item" to="/about">
              About
            </NavLink>
            <NavLink className="list-group-item" to="/home">
              Home
            </NavLink>
          </div>
        </div>
        <div className="col-xs-6">
          <div className="panel">
            <div className="panel-body">
              {/* 注册路由 */}
              <Routes>
                <Route path="/about" element={<About />}></Route>
                <Route path="/about" element={<Home />}></Route>
              </Routes>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

src\pages\Home.jsx

import React from "react";

export default function Home() {
  return (
    <div>
      <h3>我是Home的内容</h3>
    </div>
  );
}

src\pages\About.jsx

import React from "react";

export default function About() {
  return (
    <div>
      <h3>我是About的内容</h3>
    </div>
  );
}

页面效果

手把手教你React-Router6【万字详细长文】

NavLink和Link

设置路由的第一步,需要使用NavLink标签或者Link标签,指定跳转的路由路径。

<NavLink className="list-group-item" to="/about">
  About
</NavLink>

上述代码中,通过设置 to 属性来导航到指定的路由路径

NavLink 和 Link 都是 React Router 库中的组件,用于实现页面路由导航,让用户可以在单页应用中自由地切换页面视图。

Link 组件是最简单的路由导航器,它可以通过设置 to 属性来导航到指定的路由路径。例如:

<Link className="list-group-item" to="/about">
  About
  </Link>

NavLink的高亮效果

NavLink 组件在实现路由导航功能的同时,还提供了一些额外的样式控制功能,例如可以为当前活跃路由添加自定义样式或类名。使用时,将className的返回值写成一个函数即可

// src\App.jsx
<div className="list-group">
  {/* 路由链接 */}
  <NavLink className={({ isActive }) => (isActive ? "list-group-item myCustomClassName" : "list-group-item")} to="/about">
    About
  </NavLink>
  <NavLink className="list-group-item" to="/home">
    Home
  </NavLink>
</div>

// 引入自定义样式内容
.myCustomClassName {
  background: red !important;
}

页面效果

手把手教你React-Router6【万字详细长文】

在这个例子中,className 属性是一个函数,函数返回了样式类名。这个匿名函数接受一个参数

<NavLink className={(a) => {console.log(a);}} to="/about">
              About
            </NavLink>

参数是一个对象,包含isActive属性,因此,我们可以借助结构赋值方式拿到isActive。

手把手教你React-Router6【万字详细长文】

路由组件配置Routes 和 Route

Routes 和 Route 是 react-router-dom 包提供的两个组件,用于在 React 应用程序中进行路由。它们的作用如下:

  • Routes 组件是一个容器,用于定义一组 Route 组件。它内部可以包含零个或多个 Route 组件,并根据 URL 匹配其中的一个 Route 组件来渲染。
  • Route 组件用于定义路由。它包括一个路径(path)和一个组件(element)。当 URL 匹配该路径时,该组件将被渲染到页面上。可以在 Route 组件中定义其他属性和方法,以根据需要实现更高级的路由功能。

例如,本示例中使用 Routes 和 Route 组件设置基本路由的示例代码:

import React from "react";
import { NavLink, Routes, Route } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";

<div className="panel-body">
  {/* 注册路由 */}
  <Routes>
  <Route path="/about" element={<About />}></Route>
  <Route path="/home" element={<Home />}></Route>
  </Routes>
  </div>

上面的代码当 URL 匹配 /home 或 /about 时,分别加载对应的组件。

手把手教你React-Router6【万字详细长文】

route的 caseSensitive属性

“caseSensitive”用于指定路由匹配是否区分大小写。如果设置为true,则路由匹配将区分大小写。如果设置为false,则路由匹配将不区分大小写。

路由重定向Navigate

根据上图示例,我们会发现一个问题,当url处于http://localhost:3000/时,控制台会有警告

手把手教你React-Router6【万字详细长文】

因为,这个时候没有“/”没有对应任何路由组件。我们可以使页面处于跟路由“/”时,让他重定向到about组件,解决这个问题。

import { NavLink, Routes, Route, Navigate } from "react-router-dom";
<div className="panel-body">
  {/* 注册路由 */}
  <Routes>
    <Route path="/about" element={<About />}></Route>
    <Route path="/home" element={<Home />}></Route>
    <Route path="/" element={<Navigate to="/about" />}></Route>
  </Routes>
</div>

Navigate 是 react-router-dom 4.0+ 版本中的一个组件,它可以通过编程方式导航到一个特定的路由。它的用法有些类似于 Link 组件和 history.push 方法,但它可以根据一些条件来激活导航。我们看一个新demo

import { Navigate } from 'react-router-dom';

function App({ isAuth }) {
  return (
    {isAuth ? <Dashboard /> : <Navigate to="/login" />}
  );
}

在上面的代码中,我们使用了 Navigate 组件来导航到登录页面(即 to=”/login”),当 isAuth 的值为 false 时,会自动触发导航。当 isAuth 的值为 true 时,将会显示 组件和对应子路由。

Navigate的渲染机制

Navigate只要一渲染,就会引起视图变化。我们在Home组件中添加一写代码

import React, { useState } from "react";
import { Navigate } from "react-router-dom";

export default function Home() {
  const [sum, setSum] = useState(1);
  return (
    <div>
      <h3>我是Home的内容</h3>
      {sum === 2 ? <Navigate to="/about" /> : <h4>当前sum的值是:{sum}</h4>}
      <button onClick={() => setSum(2)}>点击将我变成2</button>
    </div>
  );
}

手把手教你React-Router6【万字详细长文】

根据上述代码,我们点击按钮时,sum === 2为真,Navigate组件渲染,然后自动跳转到了about组件

Navigate的repalce属性

replace 是 Navigate 组件的一个属性,用于在导航时替换当前的路由历史记录而不是添加新的记录。

在 React Router 中,导航时会将新的路由历史记录添加到栈顶,这会增加浏览器的回退次数和前进次数。但是,在某些情况下,这不是我们想要的行为,因为某些路由可能不应该添加到历史记录中。这时就可以通过设置 replace 属性来解决这个问题。

export default function Home() {
  const [sum, setSum] = useState(1);
  return (
    <div>
      <h3>我是Home的内容</h3>
      {sum === 2 ? <Navigate to="/about" replace /> : <h4>当前sum的值是:{sum}</h4>}
      <button onClick={() => setSum(2)}>点击将我变成2</button>
    </div>
  );
}

在上面的代码中,我们将 replace 属性设置为 true,以便使用 Navigate 组件进行路由导航时替换当前的路由历史记录。这意味着在路由导航后,浏览器的回退次数和前进次数将不会增加。手把手教你React-Router6【万字详细长文】

useRoutes路由表

useRoutes的使用

上述例子中。我们注册路由是这样实现的

<div className="panel-body">
  {/* 注册路由 */}
  <Routes>
    <Route path="/about" element={<About />}></Route>
    <Route path="/home" element={<Home />}></Route>
    <Route path="/" element={<Navigate to="/about" />}></Route>
  </Routes>
</div>

当组件很多时,这样写非常累赘,我们可以通过useRoutes解决这一问题

import React from "react";
import { NavLink, Routes, Route, Navigate, useRoutes } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";
export default function App() {
  // 定义路由表
  const ele = useRoutes([
    { path: "/about", element: <About /> },
    { path: "/home", element: <Home /> },
    { path: "/", element: <Navigate to="/about" /> },
  ]);
  return (
    <div>
      <div className="row">
        <div className="col-xs-offset-2 col-xs-8">
          <div className="page-header">
            <h2>React Router Demo</h2>
          </div>
        </div>
      </div>
      <div className="row">
        <div className="col-xs-2 col-xs-offset-2">
          <div className="list-group">
            {/* 路由链接 */}
            <NavLink className="list-group-item" to="/about">
              About
            </NavLink>
            <NavLink className="list-group-item" to="/home">
              Home
            </NavLink>
          </div>
        </div>
        <div className="col-xs-6">
          <div className="panel">
            <div className="panel-body">
              {/* 注册路由 */}
              {ele}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

useRoutes是React Router v6中的一个Hook,用于定义和渲染路由。它接受一个配置对象作为参数,该对象用于定义路由规则和对应的组件。

例如,上述代码定义了三个路由规则,分别对应不同的组件:

 const ele = useRoutes([
    { path: "/about", element: <About /> },
    { path: "/home", element: <Home /> },
    { path: "/", element: <Navigate to="/about" /> },
  ]);

useRoutes Hook返回的变量可以直接作为组件返回的jsx中的内容来渲染路由。

<div className="panel-body">
  {/* 注册路由 */}
  {ele}
</div>

项目中的优化

真实项目开发中,我们一般将配置文件抽离,方便管理

我们在src文件夹下创建routes文件夹,并创建index.js

import { Navigate } from "react-router-dom";
import About from "../pages/About";
import Home from "../pages/Home";
export default [
  { path: "/about", element: <About /> },
  { path: "/home", element: <Home /> },
  { path: "/", element: <Navigate to="/about" /> },
];

然后,我们在App.js中使用即可

import React from "react";
import { NavLink, useRoutes } from "react-router-dom";
import routes from "./routes";
export default function App() {
  const ele = useRoutes(routes);
  return (
    <div>
      <div className="row">
        <div className="col-xs-offset-2 col-xs-8">
          <div className="page-header">
            <h2>React Router Demo</h2>
          </div>
        </div>
      </div>
      <div className="row">
        <div className="col-xs-2 col-xs-offset-2">
          <div className="list-group">
            {/* 路由链接 */}
            <NavLink className="list-group-item" to="/about">
              About
            </NavLink>
            <NavLink className="list-group-item" to="/home">
              Home
            </NavLink>
          </div>
        </div>
        <div className="col-xs-6">
          <div className="panel">
            <div className="panel-body">
              {/* 注册路由 */}
              {ele}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

嵌套路由

嵌套路由的使用

接下来,我们实现如图所示的嵌套路由效果。Home页面下的tab选项卡,切换时可以跳转到不同的子路由。

手把手教你React-Router6【万字详细长文】

要实现嵌套路由,我们需要先创建对应的子路由文件

src\pages\Message.jsx

import React from "react";

export default function Message() {
  return (
    <div>
      <ul>
        <li>
          <a href="/message1">message001</a>&nbsp;&nbsp;
        </li>
        <li>
          <a href="/message2">message002</a>&nbsp;&nbsp;
        </li>
        <li>
          <a href="/message/3">message003</a>&nbsp;&nbsp;
        </li>
      </ul>
    </div>
  );
}

src\pages\News.jsx

import React from "react";

export default function News() {
  return (
    <ul>
      <li>news1</li>
      <li>news2</li>
      <li>news3</li>
    </ul>
  );
}

然后,我们在路由表里进行子路由配置

import { Navigate } from "react-router-dom";
import About from "../pages/About";
import Home from "../pages/Home";
import Message from "../pages/Message";
import News from "../pages/News";
export default [
  { path: "/about", element: <About /> },
  {
    path: "/home",
    element: <Home />,
    children: [
      { path: "news", element: <News /> },
      { path: "message", element: <Message /> },
    ],
  },
  { path: "/", element: <Navigate to="/about" /> },
];

子路由配置在父路由对象的children属性内。

最后,我们借助Outlet组件展示路由内容即可,src\pages\Home.jsx中

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

export default function Home() {
  return (
    <div>
      <h2>Home组件内容</h2>
      <div>
        <ul className="nav nav-tabs">
          <li>
            <NavLink className="list-group-item" to="news">
              News
            </NavLink>
          </li>
          <li>
            <NavLink className="list-group-item " to="message">
              Message
            </NavLink>
          </li>
        </ul>
        <Outlet></Outlet>
      </div>
    </div>
  );
}

Outlet 可以让我们更方便地定义嵌套路由。Outlet 类似于占位符,它会告诉父级路由组件在何处渲染子级路由组件。

嵌套路由to的三种写法

本示例中,匹配子路由,to有三种写法

<NavLink className="list-group-item" to="news">
  News
</NavLink>
<NavLink className="list-group-item" to="/home/news">
  News
</NavLink>
<NavLink className="list-group-item" to="./news">
  News
</NavLink>

其余写法都会出错

路由传参

现在,我们实现一个这样的效果,单击二级路由message组件内的任意一个按钮,在三级路由显示对应的信息

手把手教你React-Router6【万字详细长文】

手把手教你React-Router6【万字详细长文】

Params参数的传递与接受

参数的传递

要实现Params的传递,我们需要在路由调转时,定义好格式

src\pages\Message.jsx

import React, { useState } from "react";
import { Link, Outlet } from "react-router-dom";
export default function Message() {
  const [messages] = useState([
    { id: 1, title: "消息1", content: "锄禾日当午" },
    { id: 2, title: "消息2", content: "汗滴禾下土" },
    { id: 3, title: "消息3", content: "谁知盘中餐" },
    { id: 4, title: "消息4", content: "粒粒皆辛苦" },
  ]);
  return (
    <div>
      <ul>
        {messages.map((m) => {
          return (
            // 路由链接
            <li key={m.id}>
              <Link to={`detail/${m.id}/${m.title}/${m.content}`}>{m.title}</Link>
            </li>
          );
        })}
      </ul>
      <br />
      {/* 路由链接 */}
      <Outlet></Outlet>
    </div>
  );
}

上述代码中,我们使用Outlet进行message子路由展示

我们需要在src\routes\index.js中进行三级路由配置

import { Navigate } from "react-router-dom";
import About from "../pages/About";
import Home from "../pages/Home";
import Message from "../pages/Message";
import News from "../pages/News";
import Detail from "../pages/Detail";
export default [
  { path: "/about", element: <About /> },
  {
    path: "/home",
    element: <Home />,
    children: [
      { path: "news", element: <News /> },
      { path: "message", element: <Message />, children: [{ path: "detail/:id/:title/:content", element: <Detail /> }] },
    ],
  },
  { path: "/", element: <Navigate to="/about" /> },
];

注意,在定义路由时,我们的path需要进行占位detail/:id/:title/:content, 同时,我们需要定义message信息展示组件Detail.jsx

使用useParams接收参数

src\pages\Detail.jsx中

import React from "react";
import { useParams } from "react-router-dom";
export default function Detail() {
  const { id, title, content } = useParams();
  return (
    <div>
      <li>{id}</li>
      <li>{title}</li>
      <li>{content}</li>
    </div>
  );
}

useParams是一个React Router v5引入的新的Hook,它可以帮助我们方便地获取当前路由中的参数。如上述示例,当我们使用动态路由时detail/:id/:title/:content,我们需要获取id这个参数来显示用户特定的数据。这时就可以使用useParams来获取路由中的参数下:

const { id, title, content } = useParams();

Search参数的传递与接受

参数传递

search参数传递形式同浏览器原生的query参数

src\pages\Message.jsx

import React, { useState } from "react";
import { Link, Outlet } from "react-router-dom";
export default function Message() {
  const [messages] = useState([
    { id: 1, title: "消息1", content: "锄禾日当午" },
    { id: 2, title: "消息2", content: "汗滴禾下土" },
    { id: 3, title: "消息3", content: "谁知盘中餐" },
    { id: 4, title: "消息4", content: "粒粒皆辛苦" },
  ]);
  return (
    <div>
      <ul>
        {messages.map((m) => {
          return (
            // 路由链接
            <li key={m.id}>
              <Link to={`detail?id=${m.id}&title=${m.title}&content=${m.content}`}>{m.title}</Link>
            </li>
          );
        })}
      </ul>
      <br />
      {/* 路由链接 */}
      <Outlet></Outlet>
    </div>
  );
}

search参数不需要使用占位符,因此在src\routes\index.js中,path不需要使用占位写法

export default [
  { path: "/about", element: <About /> },
  {
    path: "/home",
    element: <Home />,
    children: [
      { path: "news", element: <News /> },
      { path: "message", element: <Message />, children: [{ path: "detail", element: <Detail /> }] },
    ],
  },
  { path: "/", element: <Navigate to="/about" /> },
];

使用useSearchParams接收参数

search参数的接收同params参数,都使用对应的Hooks函数。search参数的Hook函数名为useSearchParams

useSearchParams 用于获取当前 URL 中的查询参数,使用 useSearchParams 需要在你的组件中导入它,然后,在你的组件函数内部使用它:

// src\pages\Detail.jsx
import React from "react";
import { useSearchParams } from "react-router-dom";
export default function Detail() {
  const [search, setSearch] = useSearchParams();
  const id = search.get("id");
  const title = search.get("title");
  const content = search.get("content");
  return (
    <div>
    <li>{id}</li>
    <li>{title}</li>
    <li>{content}</li>
    </div>
  );
}

页面效果

手把手教你React-Router6【万字详细长文】

在上面的例子中,我们使用 useSearchParams 来获取当前 URL 中的查询参数。useSearchParams 返回一个元组,包含当前的查询参数对象和一个可以设置新的查询参数对象的函数 setSearchParams。

获取参数

使用useSearchParams获取参数,需要从其元素的第一个函数中获取

const [search, setSearch] = useSearchParams();
const id = search.get("id");
参数更新

我们使用元组的第二个参数setSearch方法可以更改接收到的路由参数

import React from "react";
import { useSearchParams } from "react-router-dom";
export default function Detail() {
  const [search, setSearch] = useSearchParams();
  const id = search.get("id");
  const title = search.get("title");
  const content = search.get("content");
  return (
    <div>
      <button onClick={() => setSearch("id=1111&&title=test&content=test&time=122333445566")}>更改参数</button>
      <li>{id}</li>
      <li>{title}</li>
      <li>{content}</li>
    </div>
  );
}

上述代码中,我们向setSearch中传递了自定义的search参数,当我点击按钮时,观察下变化

手把手教你React-Router6【万字详细长文】

可见,setSearch可以更改search参数,也可以更新视图

state参数

state参数不会使路由url发生变化

手把手教你React-Router6【万字详细长文】

state参数的传递

state参数的传递非常简单,标签内定义state属性即可。src\pages\Message.jsx

import React, { useState } from "react";
import { Link, Outlet } from "react-router-dom";
export default function Message() {
  const [messages] = useState([
    { id: 1, title: "消息1", content: "锄禾日当午" },
    { id: 2, title: "消息2", content: "汗滴禾下土" },
    { id: 3, title: "消息3", content: "谁知盘中餐" },
    { id: 4, title: "消息4", content: "粒粒皆辛苦" },
  ]);
  return (
    <div>
      <ul>
        {messages.map((m) => {
          return (
            // 路由链接
            <li key={m.id}>
              <Link to="detail" state={{ id: m.id, title: m.title, content: m.content }}>
                {m.title}
              </Link>
            </li>
          );
        })}
      </ul>
      <br />
      {/* 路由链接 */}
      <Outlet></Outlet>
    </div>
  );
}

state参数的接受

使用useLocation可以接收state的参数

import React from "react";
import { useLocation } from "react-router-dom";
export default function Detail() {
  const { state } = useLocation();
  return (
    <div>
      <li>{state ? state.id : null}</li>
      <li>{state ? state.title : null}</li>
      <li>{state ? state.content : null}</li>
    </div>
  );
}

useLocation是React Router中的另一个Hook,可以获取到当前页面的URL信息,并返回一个包含pathname、search、hash、state等属性的对象。它的作用是方便在React组件中获取URL信息,并根据URL信息来进行一些操作,例如根据URL信息动态加载组件、将URL参数作为props传递给组件等。

React-Router进阶

useNavigate

编程时导航。上述示例中,我们通过Link组件或者NavLink组件实现跳转,某些情况下,我们可能需要其他形式实现跳转,比如通过一个按钮实现路由跳转。这个时候,我们就需要编程式导航。

我们看一下demo

手把手教你React-Router6【万字详细长文】

这个案例中,我们使用按钮实现了类似Link标签的state传参跳转。它的通过useNavigate这个hook函数实现

import React, { useState } from "react";
import { Link, Outlet, useNavigate } from "react-router-dom";
export default function Message() {
  const [messages] = useState([
    { id: 1, title: "消息1", content: "锄禾日当午" },
    { id: 2, title: "消息2", content: "汗滴禾下土" },
    { id: 3, title: "消息3", content: "谁知盘中餐" },
    { id: 4, title: "消息4", content: "粒粒皆辛苦" },
  ]);
  const navigate = useNavigate();
  function showDetail(m) {
    navigate("detail", {
      replace: false,
      state: {
        id: m.id,
        title: m.title,
        content: m.content,
      },
    });
  }
  return (
    <div>
      <ul>
        {messages.map((m) => {
          return (
            // 路由链接
            <li key={m.id}>
              <Link to="detail" state={{ id: m.id, title: m.title, content: m.content }}>
                {m.title}
                <button onClick={() => showDetail(m)}>查看详情</button>
              </Link>
            </li>
          );
        })}
      </ul>
      <br />
      {/* 路由链接 */}
      <Outlet></Outlet>
    </div>
  );
}

其核心代码是

import React, { useState } from "react";
import { Link, Outlet, useNavigate } from "react-router-dom";
export default function Message() {
  // ...
  const navigate = useNavigate();
  function showDetail(m) {
    navigate("detail", {
      replace: false,
      state: {
        id: m.id,
        title: m.title,
        content: m.content,
      },
    });
  }
  return (
    <div>
      // ...
      <button onClick={() => showDetail(m)}>查看详情</button>
      // ...
    </div>
  );
}

navigate可以接受两个参数,第二个参数一个可选项,包含以下选项:

  • replace:当为 true 时,将当前导航记录替换为新路径,而不是在历史记录中创建一个新的导航记录。
  • state:一个任意类型的值,将其作为状态传递给新页面。

注意,navigate内我们定义的是state参数,因此,路由的接受也需要使用类似形式

src\pages\Detail.jsx

import React from "react";
import { useLocation } from "react-router-dom";
export default function Detail() {
  const { state } = useLocation();
  return (
    <div>
      <li>{state ? state.id : null}</li>
      <li>{state ? state.title : null}</li>
      <li>{state ? state.content : null}</li>
    </div>
  );
}

useInRouterContext

useInRouterContextle可以判断当前组件是否被组件包裹。

src\index.js

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

这个代码中,所有App子组件都被BrowserRouter包裹。因此,我们在任意组件内打印useInRouterContext()都为true

import { NavLink, useRoutes, useInRouterContext } from "react-router-dom";
 console.log(useInRouterContext()); // true

原文链接:https://juejin.cn/post/7249761605599559741 作者:石小石Orz

(2)
上一篇 2023年6月29日 上午10:10
下一篇 2023年6月29日 上午10:21

相关推荐

发表回复

登录后才能评论

评论列表(1条)

  • 头像
    whalesong 2024年1月16日 下午5:33

    这个网站是博主创建的吗咧嘴笑