无废话、光速上手 React-Router

在这里插入图片描述

React-Router

React Router 是一个用于 React 应用的声明式路由库。它允许开发者通过组件化的方式定义应用的路由结构,使得路由管理更加直观和可维护

安装

pnpm i react-router-dom

定义路由

定义路由有两种方式,分别是对象路由和路由组件,下面将逐步介绍这两种方式的用法

两种方式

对象路由

对象路由通过 createBrowserRouter 数组中的每一项来定义,该方式适合复杂的情况下使用

import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router-dom'function Home() {return (<><h1>Home</h1></>)
}function Cate() {return (<><h1>Cate</h1></>)
}// 核心代码
const router = createBrowserRouter([{// 路由访问路径path: "/",// 对应的页面组件element: <Home />},{path: "/cate",element: <Cate />}
])const root = ReactDOM.createRoot(document.getElementById('root')!);// 使用路由                                 
root.render(<RouterProvider router={router}></RouterProvider>
);
组件路由

直接通过组件来定义路由,这种方式适合简单的情况下使用

import ReactDOM from 'react-dom/client';
import { BrowserRouter, Route, Routes } from 'react-router-dom'function Home() {return (<><h1>Home</h1></>)
}function Cate() {return (<><h1>Cate</h1></>)
}const root = ReactDOM.createRoot(document.getElementById('root')!);root.render(<BrowserRouter><Routes><Route path="/" element={<Home />} /><Route path="/cate" element={<Cate />} /></Routes></BrowserRouter>
);

嵌套路由

当多个页面需要使用相同组件时,比如网站导航栏和底部,这两个组件通常会出现在所有页面当中,而这些公共组件我们没必要在多个页面单独引入,所以就需要用到嵌套路由

对象路由

import ReactDOM from 'react-dom/client';
import { createBrowserRouter, Outlet, RouterProvider } from 'react-router-dom'// 布局路由
function Layout() {return (<><div>这是一个通用导航栏组件</div>{/* 核心:这里一定要加 Outlet 否则无法显示子路由 */}<Outlet /><div>这是一个通用底部组件</div></>)
}function Home() {return (<><h1>Home</h1></>)
}function Cate() {return (<><h1>Cate</h1></>)
}function Login() {return (<><h1>Login</h1></>)
}const router = createBrowserRouter([{path: "/",element: <Layout />,children: [{// 定义为默认路由:当访问 / 时,会显示 Home 组件index: true,element: <Home />},{path: "/cate",element: <Cate />}]},{path: "/login",element: <Login />}
])const root = ReactDOM.createRoot(document.getElementById('root')!);root.render(<RouterProvider router={router}></RouterProvider>
);

组件路由

<BrowserRouter><Routes><Route path="/" element={<Layout />}><Route index element={<Home />} /><Route path="/cate" element={<Cate />} /></Route>{/* <Route element={<Layout />}><Route path="/" element={<Home />} /><Route path="/cate" element={<Cate />} /></Route> */}<Route path="/login" element={<Login />} /></Routes>
</BrowserRouter>

404 路由

当访问一个不存在的页面时会匹配到我们自定义的 404 路由

// 404页
function NotFound() {return (<><h1>404:页面未找到</h1></>)
}const router = createBrowserRouter([...,{path: "*",element: <NotFound />}
])
<BrowserRouter><Routes>...<Route path="*" element={<NotFound />} /></Routes>
</BrowserRouter>

动态路由

通常应用于通过 id 获取接口中对应的数据

const router = createBrowserRouter([// 单个:/cate/100{path: "/cate/:id",element: <Cate />},// 多个:/cate/100/200{path: "/cate/:one/:two",element: <Cate />},// 可选:/cate 或 /cate/100{path: "/cate/:id?",element: <Cate />},// 无限:/cate/100/200/300/400/500{path: "/cate/*",element: <Cate />}
])
<BrowserRouter><Router><Routes>{/* 路由组件不支持可选方式,但可以这样实现同样的效果 */}<Route path="/cate" element={<Cate />} /><Route path="/cate/:id" element={<Cate />} /><Route path="/cate/:one/:two" element={<Cate />} /><Route path="/cate/*" element={<Cate />} /></Routes></Router>
</BrowserRouter>

获取动态路由数据

通过 useParams() 来获取动态路由的参数数据

function Cate() {const params = useParams();return (<><h1>Cate</h1><pre>{JSON.stringify(params)}</pre></>);
}

访问:/cate/100/200

结果:{"one":"100","two":"200"}

路由跳转

通过 Link 进行路由跳转,其实它的本质还是通过 a 标签进行跳转的

<Link to="/cate">跳转</Link>
{/* 最终会编译成 */}
<a href="/cate">跳转</a>

声明式跳转

function Layout() {return (<><div>这是一个通用导航栏组件</div><Outlet /><div>这是一个通用底部组件</div></>)
}function Home() {return (<><h1>Home</h1><Link to="/cate">跳转到分类页</Link><Link to="/cate/100">跳转到分类页(带参数)</Link></>)
}function Cate() {return (<><h1>Cate</h1><Link to="/">跳转到首页</Link></>);
}const router = createBrowserRouter([{path: "/",element: <Layout />,children: [{index: true,element: <Home />},{path: "/cate/:id?",element: <Cate />}]}
])

编程式跳转

更多关于 useNavigate 的用法请见下方 API 目录

import { ..., useNavigate } from 'react-router-dom'function Home() {const navigator = useNavigate()return (<><h1>Home</h1><div onClick={() => navigator("/cate")}>跳转到分类页</div><button onClick={() => navigator("/cate/100")}>跳转到分类页(带参数)</button></>)
}

获取跳转参数

function Home() {const navigator = useNavigate()return (<><h1>Home</h1><Link to="/cate?title=大前端">跳转到分类页</Link><button onClick={() => navigator("/cate/100?title=Java")}>跳转到分类页(带参数)</button></>)
}function Cate() {// 获取路由动态参数的数据const params = useParams()// 获取查询参数?后面的数据const [searchParams] = useSearchParams()console.log(searchParams); // URLSearchParams {size: 1}return (<><h1>Cate</h1><div>{JSON.stringify(params)}</div>{/* {id: '100'} */}<div>{JSON.stringify(searchParams.get("title"))}</div>{/* Java */}</>);
}

路由模式

各个主流框架的常用路由模式有两种,分别是 historyhash 模式, ReactRouter 分别由 createBrowerRoutercreateHashRouter 函数负责创建

路由模式url表现底层原理
historyurl/loginhistory 对象 + pushState事件
hashurl/#/login监听 hashChange 事件

路由懒加载

默认情况下像以下代码在页面被访问时尽管条件为 false , 组件也一样会被加载。而如果使用了路由懒加载,那么只有条件满足时候 或者说 组件被使用时才会被加载,这样有助于性能优化及加载速度

{false && <Article>}

假设 pages 中有 HomeCate 组件,我们可以通过 lazy 将他们定义为懒加载模式

const router = createBrowserRouter([{path: "/",lazy: () => import("@/pages/Home/index.tsx")},{path: "/cate",// 可以省略:index.tsxlazy: () => import("@/pages/Cate")}
])

loader

通过 loader 函数我们可以在页面 渲染之前 传递给页面指定的数据,并通过 useLoaderData 来接收数据

function Cate() {const loaderData = useLoaderData()console.log(loaderData); // Hello Worldreturn ...
}const router = createBrowserRouter([{path: "/",element: <Layout />,children: [{index: true,element: <Home />},{page: "/cate/:id",element: <Cate />,loader: ({params}) => {return "Hello World!"}}]}
])

数据也可以是异步的,通常用于获取后端接口的数据

loader: () => {return new Promise((resolve) => {setTimeout(() => {resolve("Hello World!")}, 3000)})
}

还可以获取路由参数,通过参数来获取对应的数据

{path: "/cate/:id",element: <Cate />,loader: ({ params }) => {return new Promise((resolve) => {setTimeout(() => {resolve(`分类的参数:${params.id}`)}, 3000)})}
}

API

useLocation

该方法返回当前 location 对象,主要用于监听路由的变化执行对应的逻辑

function Home() {let location = useLocation();useEffect(() => {// 逻辑代码}, [location]);return ...;
}

假如访问:/cate/100?title=Java#123,那么 location 的结果如下

{"pathname":"/cate/100","search":"?title=Java","hash":"#123","state":{"data":"Hello World!"},"key":"8lu1q217"}

useNavigate

该方法主要用于编程式导航的跳转

function Home() {const navigator = useNavigate()return (<><div onClick={() => navigator("/cate")}>跳转</div></>)
}

replace

指定 replace: true 将替换历史记录堆栈中的当前条目,而不是添加新的条目。简单来说就是默认情况下它的值为 false 也就意味着当你从 A 页面跳转到 B 页面时,点击浏览器的回退功能可以正常回退到 A 页面。但如果将值设置为 true 则跳转到 B 页面时无法回退到 A 了,因为 A 的历史记录栈被 B 替换了

navigator("/cate", { replace: true })
<Navigate to="/cate" replace />

preventScrollReset

默认情况下该参数的值为 false,表示组件重新渲染或重新跳转进入时会自动滚到顶部,如果设置为 true 则表示保持当前位置

state

在跳转时也可以通过 state 进行传递数据,通过 useLocation 接收数据

navigator("/cate", { state: { data: "Hello World!" } })
<Navigate to="/cate" state={{ data: "Hello World!" }} />

示例:

function Home() {const navigator = useNavigate()return (<><h1>Home</h1><div onClick={() => navigator("/cate", { state: { data: "Hello World!" } })}>跳转</div></>)
}function Cate() {const location = useLocation()return (<><h1>Cate</h1><div>{JSON.stringify(location.state)}</div>{/* {"data":"Hello World!"} */}</>);
}

<Navigate> 该组件会在渲染时自动重定向到指定的路径。它是 useNavigate 的组件包装器,并接受与 props 相同的所有参数

我们可以应用于以下场景:当有 token 时显示页面,反之跳转到 login

import { Navigate } from 'react-router-dom'const AuthRoute = ({ children }: { children: React.ReactNode }) => {const token = "..."if (token) {return <>{children}</>} else {return <Navigate to="/login" replace />}
}export default AuthRoute

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

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

相关文章

AIGC时代 | 从零到一,打造你的专属AI Chat应用!

文章目录 目标功能概要&#xff08;1&#xff09;Chat 交互界面&#xff08;2&#xff09;流式接口&#xff08;3&#xff09;多轮会话&#xff08;4&#xff09;打字效果 系统架构&#xff08;1&#xff09;大模型服务层&#xff08;2&#xff09;应用服务层&#xff08;3&…

深入解析东芝TB62261FTG,步进电机驱动方案

TB62261FTG是一款由东芝推出的两相双极步进电机驱动器&#xff0c;采用了BiCD工艺&#xff0c;能够提供高效的电机控制。这款芯片具有多种优秀的功能&#xff0c;包括PWM斩波、内置电流调节、低导通电阻的MOSFET以及多种步进操作模式&#xff0c;使其非常适合用于需要精确运动控…

微信小程序的日期区间选择组件的封装和使用

组件化开发是一种将大型软件系统分解为更小、更易于管理和复用的独立模块或组件的方法。这种方法在现代软件开发中越来越受到重视&#xff0c;尤其是在前端开发领域。微信小程序的日期区间选择组件的使用 wxml 代码 <view><view bind:tap"chooseData">…

第一个Qt程序

创建项目 进入ui界面拖一个按钮 在头文件中添加函数说明 #ifndef HELLO_H #define HELLO_H#include <QMainWindow>QT_BEGIN_NAMESPACE namespace Ui { class Hello; } QT_END_NAMESPACEclass Hello : public QMainWindow {Q_OBJECTpublic:Hello(QWidget *parent nullpt…

上海亚商投顾:沪指缩量调整 NMN概念股逆势大涨

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 市场全天震荡调整&#xff0c;三大指数午后一度跌超1%&#xff0c;北证50指数则涨超4%&#xff0c;北交所个股…

前端发送请求格式

1.multipart/form-data格式发送请求参数 什么时候用&#xff1a; 当后端API要求以表单的形式接收数据时&#xff0c;比如<input type"text" name"username">和<input type"password" name"password">&#xff0c;这些数据…

html全局属性、框架标签

常用的全局属性&#xff1a; 属性名含义id 给标签指定唯一标识&#xff0c;注意&#xff1a;id是不能重复的。 作用&#xff1a;可以让label标签与表单控件相关联&#xff1b;也可以与css、JavaScript配合使用。 注意&#xff1a;不能再以下HTML元素中使用&#xff1a;<hea…

自动化部署-01-jenkins安装

文章目录 前言一、下载安装二、启动三、问题3.1 jdk版本问题3.2 端口冲突3.3 系统字体配置问题 四、再次启动五、配置jenkins5.1 解锁5.2 安装插件5.3 创建管理员用户5.4 实例配置5.5 开始使用5.6 完成 总结 前言 spingcloud微服务等每次部署到服务器上&#xff0c;都需要本地…

鸿蒙到底是不是纯血?到底能不能走向世界?

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 2016年5月鸿蒙系统开始立项。 2018年美国开始经济战争&#xff0c;其中一项就是制裁华为&#xff0c;不让华为用安卓。 2019年8月9日华为正式发布鸿蒙系统。问题就出在这里&#xff0c;大家可以仔细看。 安卓一…

从零开始学五笔(三):横区字根

从 1 区开始讲解字根&#xff1a; 先介绍按键的区位号、口诀内容、口诀说明然后列每个字根能组成什么汉字&#xff0c;难拆字将用中括号标出 ‍ G 键 区位号&#xff1a;11 口诀&#xff1a;王旁青头戋&#xff08;兼&#xff09;五一 说明&#xff1a; 王旁&#xff1a…

VUE, element-plus, table分页表格列增加下拉筛选多选框,请求后台

简介 为了方便表格查询时可以筛选列的值&#xff0c;需要给列增加筛选框&#xff08;多选框&#xff09;&#xff0c;element-plus提供了列的filter字段&#xff0c;但是基于表格数据的筛选&#xff0c;不会重新请求后台&#xff0c;而且当前表格数据有多少个条目&#xff0c;…

荣耀MagicOS 9.0发布会及开发者大会丨一图读懂应用服务及商业合作分论坛

更多优质流量变现服务&#xff0c;可点击荣耀广告变现服务查看&#xff1b; 荣耀远航计划——应用市场【耀闪行动】全新上线&#xff0c;更多激励及资源扶持可点击荣耀应用市场耀闪行动查看。

香港大学联合上海AI LAB,提出首个人机交互一体化大模型

导读&#xff1a; 具身智能为人与机器人的交互带来了更多便利&#xff0c;利用大语言模型&#xff08;LLMs&#xff09;的推理能力&#xff0c;能够将人类的语言指令逐步转换为机器人可以理解的指令信号。 然而&#xff0c;由于缺乏环境信息作为机器人理解环境和人类指令的上…

FPGA开发verilog语法基础1

文章目录 主体内容1.1 逻辑值1.2 数字进制格式1.3 数据类型1.3.1 寄存器类型1.3.2 线网类型1.3.3 参数类型1.3.4 存储器类型 参考资料 主体内容 1.1 逻辑值 1&#xff0c;逻辑0&#xff0c;表示低电平 2&#xff0c;逻辑1&#xff0c;表示高电平 3&#xff0c;逻辑X&#xff0…

网站安全问题都有哪些,分别详细说明

网站安全问题涉及多个方面&#xff0c;以下是一些常见的网站安全问题及其详细说明&#xff1a; 数据泄露 问题描述&#xff1a;数据泄露是指网站存储的用户敏感信息&#xff08;如用户名、密码、信用卡信息等&#xff09;被非法获取。黑客可能通过SQL注入、XSS攻击等手段窃取这…

学习分布式系统我来助你!【基本知识、基础理论、设计模式、应用场景、工程应用、缓存等全包含!】

基本知识 什么是分布式 分布式系统是一种通过网络连接多个独立计算机节点&#xff0c;共同协作完成任务的系统架构&#xff0c;具有高度的可扩展性、容错性和并发处理能力&#xff0c;广泛应用于大数据处理、云计算、分布式数据库等领域。 通俗来讲&#xff1a;分布式系统就…

git入门操作(2)

文章目录 git入门操作&#xff08;2&#xff09;git diff 查看差异git diff gitignore忽略文件1.在代码仓库创建这个文件2.添加对 log 文件过滤 连接远程仓库与ssh配置远程仓库和本地仓库关联步骤分支基本操作步骤命令&#xff1a; 合并冲突分支合并逻辑1.新建分支 dev&#xf…

ONLYOFFICE 文档8.2版本已发布:PDF 协作编辑、改进界面、性能优化等更新

ONLYOFFICE 在线编辑器最新版本已经发布&#xff0c;其中包含30多个新功能和500多个错误修复。阅读本文了解所有更新。 关于 ONLYOFFICE 文档 ONLYOFFICE 是一个开源项目&#xff0c;专注于高级和安全的文档处理。坐拥全球超过 1500 万用户&#xff0c;ONLYOFFICE 是在线办公领…

Tcp_Sever(线程池版本的 TCP 服务器)

Tcp_Sever&#xff08;线程池版本的 TCP 服务器&#xff09; 前言1. 功能介绍及展示1.1 服务端连接1.2 客户端连接&#xff08;可多个用户同时在线连接服务端&#xff09;1.3 功能服务1.3.1 defaultService&#xff08;默认服务&#xff09;1.3.2 transform&#xff08;大小写转…

【Qt】qss 设置通过 addAction 添加的 QToolButton的图标

文章目录 1. 使用 QSS 和状态示例代码2. 使用 QSS 动态更改图标QSS 示例总结 在 Qt 中&#xff0c;QSS 不能直接用于为 QAction 设置图标&#xff0c;因为 QSS 主要用于样式和外观的设置&#xff0c;而不是用于数据&#xff08;如图标&#xff09;的设置。 不过&#xff0c;你…