Redux (八) 路由React-router、嵌套路由、路由传参、路由懒加载

文章目录

  • 一、React-Router的基本使用
    • 1. 安装及基本使用(路由映射配置)
    • 2. 路由跳转Link与NavLink
    • 3. Navigate导航
    • 4. 处理路径不存在的情况
  • 二、嵌套路由
  • 三、手动跳转 (类似编程式路由导航)
    • 1. 函数式组件
    • 2. 类组件实现手动跳转
  • 四、路由传参
    • 1. 路径设置占位符(params)
    • 2. search传递参数
  • 五、路由配置到单独的文件中(useRoutes)
  • 六、路由懒加载

一、React-Router的基本使用

1. 安装及基本使用(路由映射配置)

安装:

npm install react-router-dom

react-router最主要的时提供了一系列重要的组件,

(1) 设置路由模式
路由有两种模式:hash和history,对应react-router里的两个组件HashRouterBrowserRouter

HashRouter : 设置应用的路由采用hash模式

import { HashRouter } from 'react-router-dom';
root.render(<HashRouter><App /></HashRouter>
);

BrowserRouter: 设置应用的路由采用history模式

import { HashRouter, BrowserRouter } from 'react-router-dom';
root.render(<BrowserRouter><App /></BrowserRouter>
);

hash模式地址有#,history模式没有,开发更习惯用hash模式。

(2) 路由的映射配置
Routes组件:包裹所有的Route
Route: 用于设置路径与组件的对应关系,有两个属性:
path属性: 用于设置路径
element属性: 设置路径对应的组件.

import { Route, Routes } from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
export class App extends PureComponent {render () {return (<div><div className="header"><h2>Header</h2></div><hr /><div className='content'><Routes>{/* /home路径对应Home组件 */}<Route path='/home' element={<Home />} /><Route path='/about' element={<About />} /></Routes></div><hr /><div className="footer"><h2>Footer</h2></div></div>)}
}

在这里插入图片描述

2. 路由跳转Link与NavLink

LinkNavLink有点像vue里的router-link,to属性指定跳转的路径。最终都会被渲染称a元素。
两者的区别是:NavLink在被选中时,会自动加上active的类名。可以借此设置一些样式
在这里插入图片描述
点击不同的链接:

在这里插入图片描述

3. Navigate导航

该组件用于路由的重定向,当这个组件出现时,会跳转到对应的to路径中。

比如用户在登录页,当点击登录按钮时,自动跳转到home页面。

import { Navigate } from 'react-router-dom'export class Login extends PureComponent {constructor() {super()this.state = {isLogin: false}}login () {this.setState({ isLogin: true })}render () {const { isLogin } = this.statereturn (<div><h3>登录界面</h3>{/* isLogin为true,则跳转到home页面,否则显示按钮 */}{isLogin ? <Navigate to='/home' /> : <button onClick={e => this.login()}>登录</button>}</div>)}
}
export default Login

还有路由重定向问题;当路径为/时,需要重定向到别的页面,比如重定向到首页。

   <div className='content'><Routes>{/* 重定向方式一: */}<Route path='/' element={<Navigate to='/login' />} />{/* 重定向方式二: */}<Route path='/' element={<Home />} /><Route path='/home' element={<Home />} /><Route path='/about' element={<About />} /><Route path='/login' element={<Login />} /></Routes></div>

4. 处理路径不存在的情况

随便输入一个不存在的网址:

http://localhost:3000/#/abc

针对这种情况,一般会单独写一个NotFound的页面,提示用户页面不存在。
我们通过 设置路径为通配符*来映射到NotFound页面。

     <div className='content'><Routes>{/* 重定向方式一: */}<Route path='/' element={<Navigate to='/login' />} />{/* 重定向方式二: */}<Route path='/' element={<Home />} /><Route path='/home' element={<Home />} /><Route path='/about' element={<About />} /><Route path='/login' element={<Login />} />{/* 路径一路匹配,匹配不到,说明路径不存在时,最后通过通配符*,跳转到NotFound页面 */}<Route path='/*' element={<NotFound />} /></Routes></div>

二、嵌套路由

在这里插入图片描述
在content里显示Home组件的内容,Home组件里又显示推荐、排行等子组件。
现在要实现点击推荐、排行,显示对应的组件。

App.jsx

<div className='content'><Routes>{/* 重定向 */}<Route path='/' element={<Navigate to='/home' />} /><Route path='/home' element={<Home />} >{/* 跳转到首页时,自动重定向到推荐页面 */}<Route path='/home' element={<Navigate to='/home/recommend' />} />{/* 嵌套路由 */}<Route path='/home/recommend' element={<HomeRecommend />} /><Route path='/home/rank' element={<HomeRanking />} /><Route path='/home/songmenu' element={<HomeSongMenu />} /></Route><Route path='/about' element={<About />} /><Routes/>
<div/>

嵌套路由就是在Route的双标签里,写子组件的路由Route

由于是Home页面内嵌套显示其他页面,所以Home.js:

return (<div><h3>Home</h3><Link to='/home/recommend'>推荐</Link><Link to='/home/rank'>排行</Link><button>歌曲目录</button>{/* 占位,推荐,排行,歌曲目录的子组件在这儿展示 */}<Outlet /></div>
)
}

Outlet用于在父路由组件中子路由的占位,

三、手动跳转 (类似编程式路由导航)

react-router-dom提供了函数useNavigate,调用它会返回一个函数,执行该函数并将跳转路径传入就会实现跳转。但是useNavigate这个hook只能在函数式组件中使用。

1. 函数式组件

比如组件About

//App.jsx,在App组件中,其路由嵌套关系为:<Route path='/about' element={<About />} ><Route path='/about/singers' element={<Singers />} /><Route path='/about/platform' element={<Platform/>} /></Route>//About.jsx 点击关于歌手按钮,实现页面跳转。
import React from 'react'
import { useNavigate, Outlet } from 'react-router-dom'
function About (props) {const nav = useNavigate()  //调用hookfunction navigateTo (path) {nav(path)}return (<div><h2>About</h2><button>关于平台</button><button onClick={e => navigateTo('/about/singers')}>关于歌手</button>{/* 占位符,子组件 Singers的内容会展示在这里 */}<Outlet /></div>)
}export default About

2. 类组件实现手动跳转

类组件要实现手动跳转,需要通过高阶组件给其注入useNavigate()返回的函数。

// with_router.js
import { useNavigate } from 'react-router-dom'
function withRouter (OriginComponent) {
// useNavigate 只有高阶组件在用,所以只能返回一个函数组件return function (props) {const nav = useNavigate()// nav放进对象里,注入到组件的props里return <OriginComponent {...props} router={{ nav }} />}
}
export default withRouter

组件内:

// Home组件,页面的图片在上一节嵌套路由出现过
export class Home extends PureComponent {navigateTo (path) {this.props.router.nav(path)}render () {return (<div><h3>Home</h3><Link to='/home/recommend'>推荐</Link><Link to='/home/rank'>排行</Link><button onClick={e => this.navigateTo('/home/songmenu')}>歌曲目录</button>{/* 占位 */}<Outlet /></div>)}
}
export default withRouter(Home)

四、路由传参

1. 路径设置占位符(params)

设置占位:

在这里插入图片描述
  Detail组件接收这种通过占位符传递的参数,需要用到一个hook函数useParams(),但它也只能在函数组件中使用。所以我们可以在高阶组件中使用useParams(),将得到的参数注入到Deatilprops中。

还是上面封装的那个高阶组件with_router.js

import { useNavigate, useParams} from 'react-router-dom'
function withRouter (OriginComponent) {return function (props) {// 1. 导航const nav = useNavigate()// 2. 动态路由参数--paramsconst params = useParams()const router = { nav, params, }return <OriginComponent {...props} router={router} />}
}
export default withRouter

Detail.jsx

import React, { PureComponent } from 'react'
import withRouter from '../hoc/with_router'
export class Detail extends PureComponent {render () {const { params } = this.props.routerreturn (<div><h2>Detail</h2><h3>获取到的id是:{params.id}</h3></div>)}
}
export default withRouter(Detail)

在这里插入图片描述

2. search传递参数

参数通过?拼接到url中(类似query参数)。
在这里插入图片描述
与上边类似,可以借助useSearchParams()获取到路径里拼接的参数。由于这也是一个hook,所以我们也在高阶组件里调用useSearchParams(),得到参数,注入到组件的props中。

with_router.js

import { useNavigate, useParams, useSearchParams } from 'react-router-dom'function withRouter (OriginComponent) {return function (props) {// 1. 导航const nav = useNavigate()// 2. 动态路由参数--paramsconst params = useParams()// 3. 字符串参数(query)---const [searchParams] = useSearchParams()// console.log(searchParams.get('name'));const query = Object.fromEntries(searchParams.entries())const router = { nav, params, query }return <OriginComponent {...props} router={router} />}
}
export default withRouter

此处再补充一个hookuseLocation,也可以获取到字符串拼接的值

    const location = useLocation()console.log('location', location);

在这里插入图片描述

Login.jsx
组件接收数据:

export class Login extends PureComponent {render () {const { query } = this.props.routerreturn (<div><h3>登录界面</h3><h4>query参数 --{query.name}--{query.age}</h4></div>)}
}
export default withRouter(Login)

在这里插入图片描述

五、路由配置到单独的文件中(useRoutes)

总在App.jsx里写,不直观且代码较为复杂;
在这里插入图片描述
因此将路由的映射关系单独配置到到文件router/idnex.js

// 写了几个代表性的
const routes = [{path: './',element: <Navigate to='/home' /> //重定向},{path: '/home',element: <Home />,children: [{path: '/home',element: <Navigate to='/home/recommend' />},{path: '/home/recommend',element: <HomeRecommend />},{path: '/home/rank',element: <HomeRanking />}]},{path: '/detail/:id',element: <Detail />},
... {path: '*',element: <NotFound />},
]export default routes

  在App组件中,用到useRoutes来将这些routes转换成原来的Routes这样的标签元素。但useRoutes是个hook,因此采用高阶组件将其注入到App组件中:

function withRouter (OriginComponent) {return function (props) {const routeEle = useRoutes(routes)return <OriginComponent {...props} routeEle={routeEle} />}
}

在这里插入图片描述

六、路由懒加载

(1)将路径改为懒加载
在这里插入图片描述
 改为懒加载的路径,会单独打到一个文件里,当用的时候再去加载这个文件。否则会全都打包到一个文件里。

(2)包裹Suspense 标签

import React, { Suspense } from 'react';
...
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HashRouter>{/* 包裹Suspense 标签,当路由加载还未显示在页面上时,显示fallback里的内容 */}<Suspense fallback={<h3>路由懒加载中!!</h3>}><App /></Suspense></HashRouter>
);

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

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

相关文章

Java面试指南:Java基础介绍

这是《Java面试指南》系列的第1篇&#xff0c;本篇主要是介绍Java的一些基础内容&#xff1a; 1、Java语言的起源 2、Java EE、Java SE、Java ME介绍 3、Java语言的特点 4、Java和C的区别和联系&#xff1f; 5、面向对象和面向过程的比较 6、Java面向对象的三大特性&#xff1a…

leetcode30:串联所有单词的字串

给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如&#xff0c;如果 words ["ab","cd","ef"]&#xff0c; 那么 "abcdef…

1. 解读DLT698.45-2017通信规约--预连接响应

国家电网有限公司企业标准&#xff0c;面向对象的用电信息数据交换协议DLT698.45-2017 为提高用电信息采集系统的业务适应性、采集效率、安全性和数据溯源性&#xff0c;规范用电信息数据交换协议的通信架构、数据链路层、应用层、接口类与对象标识&#xff0c;制定本标准。 …

Linux系统:(Linux系统概述与安装)

硬件计算机硬件是指计算机系统中所有物理部件的总称。包括计算机主机、显示器、键盘、鼠标、内存、硬盘、处理器、主板等等。这些硬件部件是计算机系统运行的基础 不管是电脑系统(个人电脑、服务器等)、还是移动端操作系统(手机、平板等)。它的功能就是做为用户和硬件之间的桥梁…

前端求职简历-待补充

当然可以&#xff0c;针对大厂的前端岗位&#xff0c;一个吸引人的简历应该突出你的技术能力、项目经验、教育背景以及任何能体现你学习能力和团队协作能力的证明。以下是一个简历大纲示例&#xff0c;你可以根据自己的实际情况进行调整&#xff1a; 个人信息 姓名联系方式&a…

图文深入介绍oracle资源管理(续)

1. 引言&#xff1a; 本文将承接上篇继续深入介绍oracle资源管理。本文重点介绍如何使用oracle资源管理器管理好DB。 2. 资源管理器&#xff1a; 可以使用图形界面 OEM$或命令行调用 DBMS RESOURCE MANAGER 程序包的过程进行数据库资源管理。 调用资源管理器的先决条件&…

瑞数后缀加密怎么处理

前言&#xff1a; 瑞数我们经常补环境通过&#xff0c;但是遇到瑞数后缀不知道怎么处理 就拿瑞数4来讲 解决方法&#xff1a; &#xff08;1&#xff09;传明文加密参数 一般情况&#xff0c;我们传明文加密参数也能访问 &#xff08;2&#xff09;再补环境基础调用open …

基于stm32的4G模块点灯实验

led模块功能封装 #include "led.h" #include "sys.h"//初始化GPIO函数 void led_init(void) {GPIO_InitTypeDef gpio_initstruct;//打开时钟__HAL_RCC_GPIOB_CLK_ENABLE();//调用GPIO初始化函数gpio_initstruct.Pin GPIO_PIN_8 | GPIO_PIN_9;gpio_inits…

排序算法 —— 直接插入排序

目录 1.直接插入排序的思想 2.直接插入排序的实现 实现分析 实现代码 3.直接插入排序的分析 时间复杂度分析 空间复杂度分析 稳定性 1.直接插入排序的思想 直接插入排序的思想就是把待排序的元素按其关键码值的大小依次插入到一个已经排好序的有序序列中&#xff0c…

pycharm调试带参数命令行的程序

点击 run configuration 点击加号&#xff0c;选择python name填写程序名字&#xff0c;script填写程序路径&#xff0c;下一行填写传入的参数 点击apply&#xff0c;再点ok&#xff0c;即可debug 参考&#xff1a; pycharm 调试模式下命令行参数的传递_pycharm debug传参 ya…

项目实战:构建 effet.js 人脸识别交互系统的实战之路

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀构建 effet.js &#x1f4d2;1. 什么是effet.js&#x1f4dc;2. 为什么需要使用effet.js&#x1f4dd;3. effet.js的功能&#x1f4da;4. 使用…

【项目案例】-音乐播放器-Android前端实现-Java后端实现

精品专题&#xff1a; 01.C语言从不挂科到高绩点 https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482 02. SpringBoot详细教程 https://blog.csdn.ne…

HTML之表单设计

1、HTML表单 HTML表单是用于收集用户输入的信息&#xff0c;并将用户输入的内容信息传到后台服务器中。 表单是通过form标签实现。 特别注意&#xff1a;如果一些内容提交后&#xff0c;没有将内容提交给后台服务器&#xff0c;那么需要添加一个name属性&#xff0c;语法&am…

NC 单据模板自定义项 设置参照(自定义参照)

NC 单据模板自定义项 设置参照&#xff08;自定义参照&#xff09; 如图下图&#xff0c;NC 单据模板自定义项 设置参照&#xff1a; 1、选择需要设置参照的自定义字段&#xff0c;选择高级属性页签&#xff0c;在类型设置中&#xff0c;数据类型选择参照信息&#xff0c;即bd…

【热门主题】000004 案例 Vue.js组件开发

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…

JavaWeb合集11-Maven高级

十一、Maven高级 1、分模块设计与开发 为什么?将项目按照功能拆分成若干个子模块,方便项目的管理维护、扩展,也方便模块间的相互调用&#xff0c;资源共享。 分模块开发需要先针对模块功能进行设计&#xff0c;再进行编码。不会先将工程开发完毕,然后进行拆分。 实现步骤&…

RabbitMQ下载与配置

安装Erlang Erlang 下载地址如下&#xff1a; https://erlang.org/download/otp_versions_tree.html 安装 RabbitMQ RabbitMQ 下载地址如下&#xff1a; https://www.rabbitmq.com/install-windows.html 查看服务&#xff0c;服务已经正常启动 打开Command Prompt 输入rabb…

bash之基本运算符

一.算术运算符 vim test.sh #!/bin/basha10 b20valexpr $a $b echo "a b : $val"valexpr $a - $b echo "a - b : $val"valexpr $a \* $b echo "a * b : $val"valexpr $b / $a echo "b / a : $val"valexpr $b % $a echo "b % a …

TH-OCR:强大的光学字符识别工具与车牌识别应用

在当今数字化的时代&#xff0c;高效准确地识别文本和图像中的字符变得至关重要。TH-OCR&#xff08;清华 OCR&#xff09;作为一款优秀的光学字符识别软件&#xff0c;以其卓越的性能和广泛的应用场景&#xff0c;受到了众多用户的青睐。其中&#xff0c;车牌识别功能更是在交…

Discuz | 全站多国语言翻译和繁体本地转换插件 特色与介绍

Discuz全站多国语言翻译和繁体本地转换插件 特色与介绍 特殊&#xff1a;集成了2个开源库1.多国语言翻译 来自&#xff1a;github.com/xnx3/translate特色&#xff1a;无限使用接口 免费使用2个翻译端 带有一级和二级缓存 实现秒翻译 2.简体 繁体&#xff08;台湾&#xff09…