React07-路由管理器react-router-dom(v6)

news2025/1/13 7:31:55

react-router 是一个流行的用于 React 应用程序路由的库。它使我们能够轻松定义应用程序的路由,并将它们映射到特定的组件,这样可以很容易地创建复杂的单页面应用,并管理应用程序的不同视图。

react-router 是基于 React 构建的,因此与其他 React 库和工具集成得很好。它在许多 React 应用程序中广泛使用,并被认为是 React 中最佳实践的路由。

一、react-router-dom安装和简介

1. react-router-dom安装

使用 npm 或 yarn 安装 react-router-dom。

npm install --save react-router-dom

yarn add react-router-dom

2. react-router-dom 简介

react-router-dom 是 react-router 的一种实现方案,主要应用于网页端应用,它提供了一些常用的组件进行路由管理。

(1) Router 类组件

  • BrowserRouter:history 模式下的路由。
  • HashRouter:hash 模式下的路由。

(2) Route 组件

Route 是一个路由配置组件。

(3) Link 组件

Link 类似于 a 标签,可以用于路由跳转。

(4) useNavigate Hook

useNavigate 是一个钩子函数,可以用于路由跳转。

二、react-router-dom 基本使用

1. 引入 react-router-dom

import {BrowserRouter as Router, Routes, Route} from 'react-router-dom';

这里的 BrowserRouter as Router 相当于给 BrowserRouter 起了一个别名叫 Router。Routes 组件用于包裹 Route 组件,Route 组件的父组件必须是 Routes。

2. 简单使用

使用 BrowserRouter 组件包裹 Routes 组件,再用 Routes 组件包裹 Route 组件,在 Route 组件中定义路由信息,就实现了一个简单的 react-router 场景。

Route 组件有 path 和 element 两个属性,path 属性代表路由路径,element 属性代表要渲染的组件。

index.js

import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter as Router} from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Router>
    <App />
  </Router>
);

app.js

import './App.css';
import { Routes, Route} from "react-router-dom";
import Home from "./views/Home";
import About from "./views/About";
import Error from "./views/Error";

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

export default App;

在上面的案例中,我们定义了一个根路由,指向 Home 页面。还定义一个指定路径路由 /about,指向 About 页面,表示当我们在浏览器地址栏中的页面地址后加上 /about 时,会跳转到 About 页面。

又定义了一个通用路由,指向 Error 页面,path="*" 表示如果浏览器地址栏中的页面地址不是以上定义的2种路由(即其他路由地址)时,就会跳转到 Error 页面。

注意:BrowserRouter 组件最好放在最顶层所有组件之外,这样能确保内部组件使用 Link 做路由跳转时不出错。

3. 路由跳转

跳转路由时,如果路由路径是 / 开头的是绝对路由,否则是相对路由,即相对于当前 URL进行改变。

(1) Link 组件

Link 组件只能在 Router 组件的内部使用,to 属性代表要跳转的路由地址。

import { Link } from "react-router-dom";
<Link to="/about">To About</Link>

(2) NavLink 组件

NavLink 组件和 Link 组件的功能是一致的,区别在于 NavLink 组件可以判断其 to 属性是否是当前匹配到的路由。
NavLink组件的 style 属性或 className 属性可以接收一个函数,函数接收一个含有 isActive 字段的对象为参数,可根据该参数调整样式。

import { Link } from "react-router-dom";
<NavLink to="/about" style={({ isActive }) => ( {color: isActive ? "red" : "black"} )}>To About</NavLink>

(3) useNavigate Hook

使用 useNavigate 钩子函数,可以在 js 代码中实现路由跳转。

useNavigate 必须在 Route 的上下文中使用,即必须包裹在 Router 标签内。

import { useNavigate } from "react-router-dom";
<button onClick={() => navigate("/about")}>To About</button>

4. 路由参数

(1) 路径参数(动态路由匹配)

在 Routes 组件内定义路由。对于动态路由,使用冒号(:)来指定动态部分。例如,要定义一个动态用户路由,可以:

App.js

<Routes>
  <Route path="/user/:userId" element={<User />} />
</Routes>

这里的 :userId 是动态部分,可以匹配任何放在 /user/ 后面的路径,比如 /user/123。

在路由的目标组件中,可以使用 useParams 钩子来访问动态参数。例如,在 User 组件中,可以这样获取 userId:

User.js

mport { useParams } from 'react-router-dom';

function User {
  let { userId } = useParams();
  console.log(userId); // 123
  // 使用 userId 作为你的逻辑的一部分
}

export default User;

上述案例中,访问 /user/123 能正确获取到 userId 为123。

(2) 查询参数

查询参数不需要在路由中定义,可以使用 useSearchParams 钩子函数来处理路径中的查询参数。

查询参数位于 URL 中,用于提供额外信息以便服务器能够更具体地处理请求。它们通常出现在网页地址(URL)的末尾,并且遵循一定的格式。

在 URL 中,查询参数是通过问号(?)与网址的其它部分分隔开的,并且可以包含一个或多个键值对。每个键值对都由一个键(key)和一个值(value)组成,用等号(=)连接。如果有多个查询参数,它们之间通常用符号与(&)分隔。

例如,在 URL https://example.com/page?param1=value1&param2=value2 中, param1=value1 和 param2=value2 是查询参数,它们提供了额外的信息给服务器。

useSearchParams Hook 返回当前组件获取到的查询参数对象及修改这个对象的方法,使用方法和 useState Hook 类似。

在使用 setSearchParams 方法时,必须传入所有查询参数,否则会覆盖已有查询参数。

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

function User() {
  // 使用 useSearchParams 钩子
  const [searchParams, setSearchParams] = useSearchParams();

  // 获取查询参数
  const userId = searchParams.get('userId');

  // 设置查询参数
  const setUserId = (newUserId) => {
    setSearchParams({ userId: newUserId });
  };

  // 渲染组件
  return (
    <div>
      <p>当前的 userId 是:{userId}</p>
      <button onClick={() => setUserId('123')}>设置 userId 为 123</button>
    </div>
  );
}

export default User;

上述案例中,访问 /user?userId=123456 时,效果如下:

点击按钮后,userId 变为 123,符合预期。

(3) 状态参数

react-router 对 window.location 进行了包装,状态参数就位于包装后的 location 对象的 state 属性中。下面为包装后的 location 对象的属性:

react-router包装后的location对象
pathname主机名之后的 URL 地址
search查询参数
hash哈希值,用于确定页面滚动的具体位置
state对于 window.history.state 的包装
key每个 location 对象拥有一个唯一的 key

state 不显示在页面上,不会引起页面刷新,可用于记录用户的跳转详情或在跳转时携带信息,可以用在 Link 组件或 navigate 方法中使用状态参数。

{/* Link 中使用状态参数 */}
<Link to="/about" state={{ id: 123 }} >To About</Link>

{/* useNavigate 中使用状态参数 */}
<button onClick={() => navigate("/about", { state: { id: 456 } })}>To About</button>

在目标组件中,使用 useLocation 来获取封装后的 loaction 对象,进而获取状态参数。

const location = useLocation();
console.log(location.state);

5. 路由重定向

当在某个路径 /a ,要重定向到路径 /b 时,可以通过 Navigate 组件进行重定向到其他路径。

import { Navigate } from “react-router-dom”;

function A() {
  return <Navigate to=”/b" />;
}

export default A;

三、react-router-dom 进阶使用

1. 嵌套路由

嵌套路由是前端开发中用于组织和管理路由的一种技术,特别适用于构建具有层次结构的页面和应用程序。

在 Route 组件内定义 Route 组件实现嵌套路由,在父组件中使用 Outlet 组件作为子组件的占位符(显示匹配到的子组件)。

在嵌套路由中,如果 URL 仅匹配了父级 URL,则 Outlet 组件中会显示带有 index 属性的子路由,这个子路由称为默认路由。

例3-1:根据用户 id 显示用户详细信息

App.js

import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import Home from './views/Home';
import Users from './views/Users';
import UserList from "./views/UserList";
import UserDetail from "./views/UserDetail";

function App() {
  return (
    <Router>
      <nav>
        <Link to="/">Home</Link> |
        <Link to="/users">User</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="users" element={<Users />}>
          <Route index element={<UserList />} />
          <Route path=":userId" element={<UserDetail />} />
        </Route>
      </Routes>
    </Router>
  );
}

export default App;

Users.js

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

function Users() {
  return (
    <div>
      <h2>Users</h2>
      <nav>
        <Link to="list">User List</Link>
      </nav>
      <Outlet />
    </div>
  );
}

export default Users;

UserList.js

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

function UserList() {
  const users = [
    {id: "1", name: 'John'},
    {id: "2", name: 'Jane'},
    {id: "3", name: 'Mary'},
  ];
  return (
    <div>
      <h2>User List</h2>
      <ul>
        {users.map((user) => (
          <li key={user.id}>
            <Link to={`/users/${user.id}`}>{user.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default UserList;

UserDetail.js

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

function UserDetail() {
  const { userId } = useParams();
  const users = [
    {id: "1", name: 'John'},
    {id: "2", name: 'Jane'},
    {id: "3", name: 'Mary'},
  ];
  return (
    <div>
      <h3>User Detail</h3>
      <h3>id:{userId}</h3>
      <h3>name:{users.find((user) => user.id === userId).name}</h3>
    </div>
  )
}

export default UserDetail;

上述案例中,在根组件 App 中定义了一组嵌套路由,一级路由为 / 和 users。又在 users 中嵌套了默认路由和动态路由 :userid。

在这个嵌套路由中,Users 组件为父组件,UserList 和 UserDetail 组件为子组件。在 Users 组件中使用了 Outlet 组件,作为匹配到的子组件的占位符。可以使用在路由的任何层级。当访问 /users 时,这里触发默认路由显示 UserList 组件。当访问 /users/2 时,会显示 UserDetail 组件。

访问 /users:

访问 /users/2:

2. 多组路由

多组路由指的是在单个应用中设置多个独立的路由组,可以在不同部分的应用中实现独立的路由逻辑,增加了路由结构的灵活性和模块化。

在 react-router-dom 中,可以通过在不同的组件中定义多个 Routes 组件来实现多组路由。

例3-2 管理系统案例

App.js

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import MainSite from './views/MainSite';
import AdminPanel from './views/AdminPanel';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="*" element={<MainSite />} />
        <Route path="admin/*" element={<AdminPanel />} />
      </Routes>
    </Router>
  );
}

export default App;

MainSite.js

import { Routes, Route, Link } from 'react-router-dom';
import Home from './Home';
import About from './About';

function MainSite() {
  return (
    <div>
      <nav>
        <Link to="/">Home</Link> |
        <Link to="/about">About</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
      </Routes>
    </div>
  );
}

export default MainSite;

AdminPanel.js

import { Routes, Route, Link } from 'react-router-dom';
import Dashboard from './Dashboard';
import Users from './Users';

function AdminPanel() {
  return (
    <div>
      <nav>
        <Link to="/admin/dashboard">Dashboard</Link> |
        <Link to="/admin/users">Users</Link>
      </nav>
      <Routes>
        <Route path="dashboard" element={<Dashboard />} />
        <Route path="users" element={<Users />} />
      </Routes>
    </div>
  );
}

export default AdminPanel;

上述案例构建了一个具有两个独立路由组的应用,这两个路由组分别是主站(MainSite 组件)和管理面板(AdminPanel 组件)。MainSite 组件包含了应用的主要页面,如首页(Home)和关于页面(About);AdminPanel 组件是应用的管理面板,包含了仪表盘(Dashboard)和用户管理(Users) 界面。

App.js 中定义了应用的顶级路由结构,使用 Routes 来定义两个主要路由路径:* 和 /admin/*。每个路径指向对应的 MainSite 和 AdminPanel 组件。* 路径指向 MainSite 组件,该组件处理与主站相关的子路由。/admin/* 路径指向 AdminPanel 组件,该组件处理与管理面板相关的子路由。

当访问 / 时,展示 MainSite 组件和 Home 组件;访问 /about,展示 MainSite 组件和 About 组件;访问 /admin,展示 AdminPanel 组件;访问 /admin/dashboard,展示 AdminPanel 组件和 Dashboard 组件。

3. 布局路由

布局路由是一种组织和管理路由的方式,它允许开发者将路由与其对应的布局分开管理。这在复杂的应用中特别有用,因为它可以帮助保持代码的清晰和模块化。

布局路由是指一种模式,其中一组路由共享相同的布局组件。这意味着这些路由的所有页面都将有相同的外观和感觉,例如共享的头部和底部导航栏。布局组件负责渲染这些共享元素,而特定的子路由则负责渲染页面的主要内容。

例3-3 升级版管理系统案例

App.js

同案例3-2。

MainSite.js

import React from 'react';
import {Routes, Route, Link} from 'react-router-dom';
import Home from './Home';
import About from './About';
import Header from './Header';
import Footer from './Footer';
import Error from "./Error";

function MainSite() {
  return (
    <div>
      <Header />
      <nav>
        <Link to="/">Home</Link> |
        <Link to="/about">About</Link>
      </nav>
      <Routes>
        <Route index element={<Home />} />
        <Route path="about" element={<About />} />
        {/* 更多主站的路由可以在这里添加 */}

        {/* 捕获所有未匹配的路由并显示 Error 组件 */}
        <Route path="*" element={<Error />} />
      </Routes>
      <Footer />
    </div>
  );
}

export default MainSite;

AdminPanel.js

import React from 'react';
import {Routes, Route, Link} from 'react-router-dom';
import Dashboard from './Dashboard';
import Users from "./Users";
import AdminHeader from './AdminHeader';
import AdminFooter from './AdminFooter';
import Error from "./Error";

function AdminPanel() {
  return (
    <div>
      <AdminHeader />
      <nav>
        <Link to="/admin">Dashboard</Link> |
        <Link to="/admin/users">Users</Link>
      </nav>
      <Routes>
        <Route path="" element={<Dashboard />} />
        <Route path="users" element={<Users />} />
        {/* 更多管理面板的路由可以在这里添加 */}
        {/* 捕获所有未匹配的路由并显示 Error 组件 */}
        <Route path="*" element={<Error />} />
      </Routes>
      <AdminFooter />
    </div>
  );
}

export default AdminPanel;

上述案例中,我们在 MainSite 和 AdminPanel 中加入了 Header 和 Footer 布局组件,同时添加了一个用于处理所有未匹配路由的 Error 组件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1374536.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

谈谈Spring Bean

一、IoC 容器 IoC 容器是 Spring 的核心&#xff0c;Spring 通过 IoC 容器来管理对象的实例化和初始化&#xff08;这些对象就是 Spring Bean&#xff09;&#xff0c;以及对象从创建到销毁的整个生命周期。也就是管理对象和依赖&#xff0c;以及依赖的注入等等。 Spring 提供…

重学MySQL之关系型数据库和非关系型数据库

1 关系型数据库 1.1 关系型数据库的特性 1.1.1 事务的特性 事务&#xff0c;是指一个操作序列&#xff0c;这些操作要么都执行&#xff0c;或者都不执行&#xff0c;而且这一序列是无法分隔的独立操作单位。也就是符合原子性&#xff08;Atomicity&#xff09;、 一致性&…

C语言——结构体类型(二)【结构体内存对齐,结构体数组】

&#x1f4dd;前言&#xff1a; 上一讲结构体类型&#xff08;一&#xff09;中&#xff0c;我们讲述了有关结构体定义&#xff0c;创建&#xff0c;初始化和引用的内容&#xff0c;这一讲&#xff0c;我们进一步学习结构体的相关知识&#xff1a; 1&#xff0c;结构体内存对齐…

Delphi 11.3配置android环境

电脑安装dephi11.3的时候&#xff0c;勾选android sdk&#xff0c;但是软件安装好以后&#xff0c;还有问题 在Delphi—tool —options 里边&#xff0c;Deployment下SDKManager 中&#xff0c;看到SDk里边的感叹号&#xff0c;说明android sdk没有安装好 解决方法有2种 第一种…

MySQL从0到1全教程【1】MySQL数据库的基本概念以及MySQL8.0版本的部署

1 MySQL数据库的相关概念 1.1 数据库中的专业术语 1.1.1 数据库 (DB) 数据库是指:保存有组织的数据的容器(通常是一个文数据库 (database)件或一组文件)。 1.1.2 数据库管理系统 (DBMS) 数据库管理系统(DBMS)又称为数据库软件(产品)&#xff0c;用于管理DB中的数据 注意:…

小H靶场笔记:Empire-Breakout

Empire&#xff1a;Breakout January 11, 2024 11:54 AM Tags&#xff1a;brainfuck编码&#xff1b;tar解压变更目录权限&#xff1b;Webmin&#xff1b;Usermin Owner&#xff1a;只惠摸鱼 信息收集 使用arp-scan和namp扫描C段存活主机&#xff0c;探测靶机ip&#xff1a;1…

横版动作闯关游戏:幽灵之歌 GHOST SONG 中文版

在洛里安荒凉的卫星上&#xff0c;一件长期休眠的死亡服从沉睡中醒来。踏上发现自我、古老谜团和宇宙骇物的氛围2D冒险之旅。探索蜿蜒的洞穴&#xff0c;获得新的能力来揭开这个外星世界埋藏已久的秘密。 游戏特点 发现地下之物 探索这个广阔而美丽如画&#xff0c;充满密室和诡…

Graham扫描凸包算法

凸包&#xff08;Convex Hull&#xff09;是包含给定点集合的最小凸多边形。凸包算法有多种实现方法&#xff0c;其中包括基于递增极角排序、Graham扫描、Jarvis步进法等。下面&#xff0c;我将提供一个简单的凸包算法实现&#xff0c;基于Graham扫描算法。 Graham扫描算法是一…

关于PhpStorm的安装激活与汉化

访问官网下载PhpStorm https://www.jetbrains.com/phpstorm/download/#sectionwindows 点击download 下载好后&#xff0c;双击exe安装程序 点击下一步 选择安装位置 前两个肯定需要勾选&#xff1a; 创建桌面快捷方式&#xff1b;创建关联php&#xff1b; 根据以往经验&am…

CES 2024丨引领变革,美格智能为智能终端带来生成式AI能力

作为电子行业的“风向标”&#xff0c;CES 2024&#xff08;国际消费电子展&#xff09;于1月9日至12日在美国拉斯维加斯举办。本届展会可谓是AI的盛宴&#xff0c;芯片、AI PC、智能家居、汽车科技、消费电子等领域与AI相关的前沿成果接连发布&#xff0c;引领人工智能领域的科…

【数据库】视图索引执行计划多表查询笔试题

文章目录 一、视图1.1 概念1.2 视图与数据表的区别1.3 优点1.4 语法1.5 实例 二、索引2.1 什么是索引2.2.为什么要使用索引2.3 优缺点2.4 何时不使用索引2.5 索引何时失效2.6 索引分类2.6.1.普通索引2.6.2.唯一索引2.6.3.主键索引2.6.4.组合索引2.6.5.全文索引 三、执行计划3.1…

leaflet学习笔记-缓冲区绘制(六)

前言 在GIS开发中&#xff0c;缓冲区的绘制和使用是非常广泛的&#xff0c;一般情况下就是对缓冲区范围内的要素做分析使用&#xff0c;也会有一些其他的操作&#xff0c;下面我就记录一下使用leafletturf.js完成缓冲区的绘制操作 turf.js简介 Turf.js 是一个用于地理空间计…

上架苹果APP的时候在哪里填写APP的隐私政策信息

在如今高度重视数据隐私的时代&#xff0c;开发并上架一个iOS APP时提供透明的隐私政策是非常重要的。苹果公司对此有严格的规定&#xff0c;任何上架至App Store的应用都必须包含一个隐私政策。以下是您在上架苹果APP时填写隐私政策信息的详细步骤和必须注意的事项。 准备隐私…

考古学家 - 华为OD统一考试

OD统一考试 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 有一个考古学家发现一个石碑&#xff0c;但是很可惜发现时其已经断成多段。 原地发现N个断口整齐的石碑碎片&#xff0c;为了破解石碑内容&#xff0c;考古学家希望有程序能帮忙计算复原后的石…

最新PyCharm安装详细教程及pycharm配置_pycharm安装教程

目录 一、PyCharm简介及其下载网站 二、单击网站的Downloads&#xff0c;进入二级页面&#xff0c;选择对应的操作系统下载PyCharm 三、PyCharm的安装程序的安装及其配置(configuration) 1、运行PyCharm Setup 2、安装位置设置 3、安装选项设置 4、开始菜单中PyCharm快捷方式的…

Unity中向量的点乘、叉乘区别和作用以及经典案例

文章目录 点乘&#xff08;Dot Product&#xff09;叉乘&#xff08;Cross Product&#xff09;向量归一化&#xff08;Normalize&#xff09;其他作用 unity开发中我们要计算角度&#xff0c;判断位置&#xff0c;常用点乘、叉乘、归一化等等&#xff0c;我们看看他们的使用案…

Android 通知简介

Android 通知简介 1. 基本通知 图1: 基本通知详情 小图标 : 必须提供,通过 setSmallIcon( ) 进行设置.应用名称 : 由系统提供.时间戳 : 由系统提供,也可隐藏时间.大图标(可选) : 可选内容(通常仅用于联系人照片,请勿将其用于应用图标),通过setLargeIcon( ) 进行设置.标题 : 可选…

中国社科院大学与美国杜兰大学金融管理硕士项目——熬过寒冬,春日暖阳已不远

在金融领域&#xff0c;寒冬似乎成了无法避免的阶段。然而&#xff0c;对于那些坚守岗位的金融从业者来说&#xff0c;熬过寒冬并非无望。正如冬去春来&#xff0c;只要我们采取明智的策略&#xff0c;迈出坚定的步伐&#xff0c;春日的暖阳已在不远方照耀。社科院与美国杜兰大…

SpringBoot+Hutool实现图片验证码

图片验证码在注册、登录、交易、交互等各类场景中都发挥着巨大作用&#xff0c;能够防止操作者利用机器进行暴力破解、恶意注册、滥用服务、批量化操作和自动发布等行为。 创建一个实体类封装&#xff0c;给前端返回的验证码数据&#xff1a; Data public class ValidateCodeV…

JS栈和堆:数据是如何存储的

JS栈和堆&#xff1a;数据是如何存储的 背景JavaScript 是什么类型的语言JavaScript 的数据类型内存空间栈空间和堆空间再谈闭包 背景 JS有多种数据类型&#xff1a;数字型&#xff0c;字符串型&#xff0c;数组型等&#xff0c;虽然 JavaScript 并不需要直接去管理内存&#…