React(七):Router基本使用、嵌套路由、编程式导航、路由传参、懒加载
React(七)
- 一、React-Router的基本使用
- 1.安装和介绍
- 2.路由的配置和跳转
- 3.Navigate的使用
- 4.如果找不到对应的路由路径?
- 二、嵌套路由的用法
- 三、编程式路由导航
- 1.类组件中使用useNavigate
- 2.函数式组件中使用useNavigate
- 四、路由跳转传参
- 1.设置好路径的占位符(params)
- 2.参数直接拼接到url中(query)
- 五、路由的配置文件
- 六、路由的懒加载
一、React-Router的基本使用
1.安装和介绍
安装:
npm install react-router-dom
react-router最主要的API是给我们提供的一些组件:BrowserRouter
或HashRouter
其中BrowserRouter
使用history
模式;
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.querySelector("#root"))root.render(<BrowserRouter><App/></BrowserRouter>
)
HashRouter
使用hash
模式:
import React from "react"
import ReactDOM from "react-dom/client"
import { HashRouter } from "react-router-dom"
import App from "./App"const root = ReactDOM.createRoot(document.querySelector("#root"))root.render(<HashRouter><App/></HashRouter>
)
2.路由的配置和跳转
在App中通过使用Routes和Route
组件指定路由的出口,path
属性指定对应路径,element
属性指定要切换的组件实例。
通过Link
组件实现路由的跳转,to
属性指定切换的路径
import React, { PureComponent } from 'react';
import Home from './pages/Home';
import Search from './pages/Search';
import Detail from './pages/Detail';
import {Routes, Route, Link} from 'react-router-dom';export class App extends PureComponent {render() {return (<div><div className="header">Header<hr /><Link to='/home'>点击切换到Home</Link><hr /><Link to='/detail'>点击切换到detail</Link><hr /><Link to='/search'>点击切换到search</Link><hr /></div><div className="content">中间的路由内容<Routes><Route path='/home' element={<Home />} /><Route path='/detail' element={<Detail />} /><Route path='/search' element={<Search />} /></Routes></div><div className="foorer">Footer</div></div>)}
}export default App
3.Navigate的使用
Navigate用于路由的重定向,当这个组件出现时,就会执行跳转到对应的to路径中
比如我们举个例子,用户来到登录页:
如果没登陆就显示登录按钮;
如果点击登录按钮,就把状态设置为登录,然后就自动跳转到home页。
import React, { PureComponent } from 'react'
import { Navigate } from 'react-router-dom';export class Login extends PureComponent {constructor(props) {super(props);this.state = {isLogin: false}}login() {this.setState({isLogin: true})}render() {let { isLogin } = this.state;return (<div><h1>Login</h1>{!isLogin ? <button onClick={(() => this.login())}>登录</button> : <Navigate to='/home'/>}</div>)}
}export default Login
还有就是路由的重定向问题,如果遇到地址只有一个/
,那么就导航至home页(或者其实直接写Home组件 <Route path='/' element={<Home />} />
也可以的)
<Routes><Route path='/' element={<Navigate to='/home' />} /><Route path='/home' element={<Home />} /><Route path='/detail' element={<Detail />} /><Route path='/login' element={<Login />} /></Routes>
4.如果找不到对应的路由路径?
此时我们可以设置path='*'
时(找不到路径时),自动路由跳转到某个组件,给用户提示
<Routes><Route path='/' element={<Navigate to='/home' />} /><Route path='/home' element={<Home />} /><Route path='/detail' element={<Detail />} /><Route path='/login' element={<Login />} /><Route path='*' element={<NotFound />} /></Routes>
二、嵌套路由的用法
在vue中我们需要去配置children这个配置项,但是在react中,不需要噢。
比如我要在Home里面搞个导航栏切换对应的内容:
那么首先先建三个组件:
然后来到App,在Home页的这个Route
标签中间写嵌套的路由,这里的第一行是一个重定向,如果进入Home页,默认导航至第一个组件Column1
:
然后回到Home页,设置跳转的标签和子路由的出口<Outlet>
:
当然啊Outlet
啊,Route
啊,Link
啊这些组件别忘了引入。
三、编程式路由导航
React-router给我们提供了一个hook
,名字叫useNavigate
,调用它可以返回一个函数,我们调用这个函数并把path
传给它就可以实现随时通过点击事件进行路由的跳转。
但是既然是hook,那么就只能在函数式组件中使用,如果要在类组件中使用呢?
1.类组件中使用useNavigate
在类组件中想要使用hook并不是不可以,我们可以通过一个高阶组件,给类组件注入这个hook,然后通过props就能调用并传参。
在做高阶组件时,返回的应该是一个函数式组件(如果是类组件不还是用不了吗),然后把useNavigate
的返回值(一个函数)注入进去
import { useNavigate } from "react-router-dom";export default function enhanceUseNavigate(Component) {//这里要通过函数式组件注入,因为类组件里不能用噢return function(props) {let navigate = useNavigate();return <Component {...props} navigate={navigate}/>}
}
然后另一边使用高阶组件,并且点击按钮时调用传path就行了,这样就可以实现跳转。
export class App extends PureComponent {navigateTo(path) {//在这里就可以调用注入的跳转函数,传入path进行路由跳转this.props.navigate(path);}render() {return (<div><div className="header">Header<hr /><button onClick={() => this.navigateTo('/home')}>点击按钮跳转到Home</button><button onClick={() => this.navigateTo('/detail')}>点击按钮跳转到detail</button><button onClick={() => this.navigateTo('/login')}>点击按钮跳转到登录页</button></div><div className="content"><h4>中间的路由内容:</h4><Routes><Route path='/' element={<Navigate to='/home' />} /><Route path='/home' element={<Home />} /><Route path='/detail' element={<Detail />} /><Route path='/login' element={<Login />} /><Route path='*' element={<NotFound />} /></Routes></div><div className="foorer">Footer</div></div>)}
}export default enhanceUseNavigate(App);
2.函数式组件中使用useNavigate
这东西本来就是为函数式组件而生的,所以在这里使用简直是妙蛙种子到了米奇妙妙屋,妙到家了。
function App() {let navigate = useNavigate();function navigateTo(path) {navigate(path);}return (<div><div className="header">Header<hr /><button onClick={() => this.navigateTo('/home')}>点击按钮跳转到Home</button><button onClick={() => this.navigateTo('/detail')}>点击按钮跳转到detail</button><button onClick={() => this.navigateTo('/login')}>点击按钮跳转到登录页</button></div><div className="content"><h4>中间的路由内容:</h4><Routes><Route path='/' element={<Navigate to='/home' />} /><Route path='/home' element={<Home />} /><Route path='/detail' element={<Detail />} /><Route path='/login' element={<Login />} /><Route path='*' element={<NotFound />} /></Routes></div><div className="foorer">Footer</div></div>)
}export default App;
四、路由跳转传参
1.设置好路径的占位符(params)
类似于vue中的params参数
注意,写了占位,如果不传,那么路径就会置空
通过拼接:参数名
可以设置参数的key
,这样的话就可以把参数的value
通过Link
或编程式导航传给Detail
组件。
那么参数怎么接呢?
这里要提到另一个hook用来接收参数,useParams
,但是呢如果Detail组件是一个类组件,那么我们就要用高阶组件给它注入这个东西:
拿刚才那个高阶组件举例吧,还是同样的方法,把params注入给Detail的props。
import { useNavigate, useParams } from "react-router-dom";export default function enhanceUseNavigate(Component) {//这里要通过函数式组件注入,因为类组件里不能用噢return function (props) {let navigate = useNavigate();let params = useParams();let router = { navigate, params };return <Component {...props} router={router} />}
}
最后来到Detail组件,可以直接读取,参数传过来放到对象里,我们就能去读它的id,或者用它发请求什么的。
import React, { PureComponent } from 'react';
import enhanceUseNavigate from '../utils/enhanceUseNavigate';export class Detail extends PureComponent {render() {let { params } = this.props.router;console.log(params);//{id: '123'}return (<div><h1>Detail</h1><h2>收到路由跳转传来的参数:{params.id}</h2></div>)}
}export default enhanceUseNavigate(Detail)
2.参数直接拼接到url中(query)
类似vue中的query参数
直接在跳转的地方拼接url参数,那么怎么接呢?
这里用到另一个hook:useSearchParams
当然在函数式组件中用会比较合适,但是这里我们在类中演示吧,还是用高阶组件,拿之前那个举例:
import { useNavigate, useParams, useSearchParams } from "react-router-dom";export default function enhanceUseNavigate(Component) {//这里要通过函数式组件注入,因为类组件里不能用噢return function (props) {// 1.导航const naviagte = useNavigate()// 2.动态路由的参数const params = useParams()// 3.查询字符串的参数const [searchParams] = useSearchParams()// console.log(searchParams.get('name'))const query = Object.fromEntries(searchParams.entries())console.log(query);const router = { naviagte, params, query}return <Component {...props} router={router} />}
}
这里的写法没怎么见过,先记住吧。总之就是把传过来的url参数变成一个对象,里面存着键值对格式的参数。同样我们注入到Login
组件中,就可以接到参数了
import React, { PureComponent } from 'react'
import enhanceUseNavigate from '../utils/enhanceUseNavigate';;export class Login extends PureComponent {render() {let { query } = this.props.router;return (<div><h1>Login</h1><h2>拿到query参数!{query.name}-{query.age}</h2></div>)}
}export default enhanceUseNavigate(Login)
五、路由的配置文件
目前我们所有的路由都配置在组件中,用标签的形式写出来的,这样会比较乱,那么我们想像vue一样有自己的独立配置,react
给我们提供了这样的hook
比如我们要把下面这一堆路由关系配置成一个单独的文件
<div className="content"><h4>中间的路由内容:</h4><Routes><Route path='/' element={<Navigate to='/home' />} /><Route path='/home' element={<Home />} ><Route path='/home' element={<Navigate to='/home/column1' />}></Route><Route path='/home/column1' element={<Column1 />}></Route><Route path='/home/column2' element={<Column2 />}></Route><Route path='/home/column3' element={<Column3 />}></Route></Route><Route path='/detail/:id' element={<Detail />} /><Route path='/login' element={<Login />} /><Route path='*' element={<NotFound />} /></Routes></div>
大概就是这样的:
import Home from '../pages/Home';
import Login from '../pages/Login';
import Detail from '../pages/Detail';
import NotFound from '../pages/NotFound';
import Column1 from '../pages/Column1';
import Column2 from '../pages/Column2';
import Column3 from '../pages/Column3';
import { Navigate } from 'react-router-dom';let routes = [{path:'/',element: <Navigate to='/home'/> //重定向},{path:'/home',element: <Home/>,children: [{path:'/home',element: <Navigate to="/home/column1"/> //重定向},{path:'/home/column1',element: <Column1/>},{path:'/home/column2',element: <Column2/>},{path:'/home/column3',element: <Column3/>}]},{path:'/detail/:id',element: <Detail/>},{path:'/login',element: <Login/>},{path: '*',element: <NotFound/>}
]export default routes;
然后在App中需要导入routes,并且使用hook占位:
ok搞定
六、路由的懒加载
两步
1、换成这个
2、包个标签
import { Suspense } from 'react';
......
root.render(<HashRouter><Suspense fallback={<h3>路由懒加载加载中!!</h3>}><App /></Suspense></HashRouter>
);
这里fallback里的东西是加载没出来的时候显示的东西
相关文章:

React(七):Router基本使用、嵌套路由、编程式导航、路由传参、懒加载
React(七)一、React-Router的基本使用1.安装和介绍2.路由的配置和跳转3.Navigate的使用4.如果找不到对应的路由路径?二、嵌套路由的用法三、编程式路由导航1.类组件中使用useNavigate2.函数式组件中使用useNavigate四、路由跳转传参1.设置好路…...

Java基础面试题(一)
Java基础面试题 一、面向对象和集合专题 1. 面向对象和面向过程的区别 面向过程:是分析解决问题的步骤,然后用函数把这些步骤一步一步地实现,然后在使用的时候一一调用则可。性能较高,所以单片机、嵌入式开发等一般采用面向过程…...
代码命名规范是一种责任也是一种精神(工匠精神)
代码命名规范之美规范概述命名规范管理类命名BootstrapProcessorManagerHolderFactoryProviderRegistrarEngineServiceTask传播类命名ContextPropagator回调类命名Handler ,Callback,Trigger,ListenerAware监控类命名MetricsEstimatorAccumul…...

奇淫技巧:阅读源码时基于一组快捷键,让我们知道身在何方!
一个十分蛋疼的问题 在我们阅读框架底层源码的时候,我们往往会一个方法一个方法的往下翻,翻了很久很快就会有这样的灵魂拷问:我从那个类(方法)来,我要到哪个(类)方法中去。这个时候…...
你真的弄懂this指向了吗
前言 在说 this 指向之前,请观察以下代码,并说出它们的输出结果: 第 1 组:标准函数 window.color "red"; let o {color: "blue", }; function sayColor() {console.log(this.color); }sayColor(); // 输…...

阿里云服务器使用教程:使用xshell、xFtp工具连接阿里云服务器(Centos7)并修改Centos7的yum源为阿里镜像源
目录 1、下载并安装xshell、xFtp 2、远程连接阿里云服务器 3、 修改Centos7的yum源为阿里镜像源 1、下载并安装xshell、xFtp XShell可以在Windows界面下来访问远端不同系统下的服务器,从而比较好的达到远程控制终端的目的。它支持 RLOGIN、SFTP、SERIAL、TELNET、…...

一文快速入门 HTML 网页基础
专栏简介: 前端从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录 1.HTML 结构 1.1. 认识 HTML 标签 1.2 HTML 文件结构…...
DEJA_VU3D - Cesium功能集 之 100-任意多边形(标绘)
前言 编写这个专栏主要目的是对工作之中基于Cesium实现过的功能进行整合,有自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小140个左右的功能,后续也会不断的追加,所以暂时打算一周2-3更的样子来更新本专栏(每篇博文都会奉上完整demo的源代码,…...
Cadence OrCAD Capture全局修改原理图的非本地库符号的方法图文教程Repalce Catch功能
⏪《上一篇》 🏡《总目录》 ⏩《下一篇》 目录 1,概述2,修改方法2.1,新建本地库2.2,待修改搬入本地库2.3,修改原理图符号2.4,全局更新原理图符号3,总结B站关注“硬小二”浏览更多演示视频 1,概述 在完成原理图设计...
npm包版本号详解
npm包在发布时,需要按照包版本语义化中的约定去更新设置,例如我们常见的1.0.0,1.0.1,0.0.1等这样的版本号,那么这些数字分别代表什么意思呢?下面我们将详细介绍。 npm版本号的组成 一个完整的版本号&…...

ubuntu 系统安装docker——使用docker打包python项目,整个流程介绍
目录 1 安装docker和配置镜像源 2 下载基础镜像 3 通过镜像创建容器 4 制作项目所需的容器 5 容器制作好后打包为镜像 6 镜像备份为.tar文件 7 从其他服务器上恢复镜像 8 docker的其他常用指令 首先科普一下镜像、容器和实例; 镜像:相当于安装包&…...

MySQL事务篇
MySQL事务篇 一、一条Insert语句 为了故事的顺利发展,我们需要创建一个表: CREATE TABLE t (id INT PRIMARY KEY,c VARCHAR(100) ) EngineInnoDB CHARSETutf8;然后向这个表里插入一条数据: INSERT INTO t VALUES(1, 刘备); 现在表里的数据就…...

【Redis】搭建分片集群
目录 集群结构 准备实例和配置 启动 创建集群 测试 集群结构 分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个 master包含一个slave节点,结构如下: 这里我们会在同一台虚…...

RoCEv2网络部署实践
延续上篇RoCE网络的介绍,我们知道承载ROCEv2流量必须有一张无损网络。 本章主要介绍在以太网环境部署无损网络的关键点。 首先是QoS,包含流分类和队列调度两部分。 流分类:在网络接入设备(TOR)配置if-match类的语句&am…...

【HashMap】| 深度剥析Java SE 源码合集Ⅱ | 你会吗?
目录一. 🦁 HashMap介绍1.1 特点1.2 底层实现二. 🦁 结构以及对应方法分析2.1 结构组成2.1.1 成员变量2.1.2 存储元素的节点类型2.1.2.1 链表Node类2.1.2.2 树节点类2.1.2.3 继承关系2.2 方法实现2.2.1 HashMap的数组初始化2.2.2 计算hash值2.2.3 添加元…...

剑指 Offer 39. 数组中出现次数超过一半的数字
剑指 Offer 39. 数组中出现次数超过一半的数字 难度:easy\color{Green}{easy}easy 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: …...
使用python控制摄像头
前言 当今,随着计算机技术的发展,摄像头已经成为了人们生活中不可或缺的一部分。而Python作为一种流行的编程语言,也可以轻松地控制和操作摄像头。无论你是想用Python写一个简单的摄像头应用程序,还是想在机器学习和计算机视觉项…...

Linux文件系统
目录 1、常见的linux文件系统 2、文件系统的组成 inode的内容: 可以用stat命令,查看某个文件的inode信息 inode的大小 inode号码 使用 ls -i来查看文件的inode号码 使用 df -i命令,查看每个硬盘分区的inode总数和已经使用的数量ÿ…...

扬帆优配|引活水 增活力 促转型 创业板助力实体经济高质量发展
立异就是生产力,企业赖之以强,国家赖之以盛。全面注册制变革持续开释立异生机。日前,创业板公司已开端连续公布2022年度年度报告和2023年第一季度成绩预告,从频频传来的“喜报”中可窥见立异驱动开展战略下新兴工业的强劲开展态势…...

【c++】:STL模板中string的使用
文章目录 STL简介一.认识string二.string中基本功能的使用总结STL简介 STL(standard template libaray-标准模板库):是C标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。STL的版本 原始版本 Alexand…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...