react-router-dom 在 React Hook 中的常用组合拳

React Router DOM 是一个用于在 React 应用中实现路由功能的库。它提供了一组组件和钩子,可以帮助我们管理应用的导航和路由,结合 React Hook 的使用可以使我们的代码更加简洁和易于维护。

React Router DOM

使用版本:"react-router-dom": "^6.8.2"

一、安装

首先,我们需要安装 react-router-dom。可以使用 pnpmyarn 进行安装:

pnpm add -S react-router-dom

二、常用组合拳

1、配置路由

在使用 react-router-dom 之前,我们需要先配置路由,这里我们使用 BrowserRouter 组件来配置路由,它是 react-router-dom 提供的一个路由容器,它使用 HTML5 提供的 history API 来保持 UI 和 URL 的同步。

// router/index.jsx 

import { Suspense } from 'react'
import { BrowserRouter, Route, Routes } from 'react-router-dom'

import App from '@/App'
import Loading from '@/components/loading'
import NotAuth from '@/pages/403'
import QuestionList from '@/pages/question/list'
import TaskAdd from '@/pages/task/add'
import TaskDetail from '@/pages/task/detail'
import TaskList from '@/pages/task/index'
import TaskIssues from '@/pages/task/issues'
import TaskVersion from '@/pages/task/version'

console.log('BASE_URL:', import.meta.env.BASE_URL)

function Routers() {
  return (
      <Suspense fallback={<Loading />}>
        <BrowserRouter
            basename={
                import.meta.env.NODE_ENV === 'production' ? '/web/' : '/'
            }
        >
          <Routes>
            <Route path="/" element={<App />}>
              <Route index element={<QuestionList />}></Route>
              <Route path="/task-list" element={<TaskList />}></Route>
              <Route path="/add-task" element={<TaskAdd />}></Route>
              <Route path="/task-detail" element={<TaskDetail />}></Route>
              <Route path="/issues" element={<TaskIssues />}></Route>
              <Route path="/version" element={<TaskVersion />}></Route>
              <Route path="/403" element={<NotAuth />}></Route>
            </Route>
            <Route path="*" element={<Navigate to="/" />}></Route>
          </Routes>
        </BrowserRouter>
      </Suspense>
  )
}

export default Routers

2、挂载使用路由

main.jsx 中,我们需要将 Routers 组件挂载到 root 节点上,这样我们的路由就可以正常使用了。

// main.jsx

import './assets/css/style.scss'
import 'dayjs/locale/zh-cn'

import { ConfigProvider } from 'antd'
import { message } from 'antd'
import zhCN from 'antd/locale/zh_CN'
import ReactDOM from 'react-dom/client'

message.config({
  getContainer: () => document.querySelector('.app-container'),
})

ReactDOM.createRoot(document.getElementById('root')).render(
    <ConfigProvider locale={zhCN}>
      <Routers />
    </ConfigProvider>
)

3、在根组件中使用 Outlet 组件,用于渲染子路由。

Routers 组件中,我们使用 Route 组件来配置路由,但是在 App 组件中,我们需要使用 Outlet 组件来渲染子路由。

// App.jsx

import { AppstoreOutlined, CodeOutlined } from '@ant-design/icons'
import { Avatar, Dropdown, Menu } from 'antd'
import { useEffect, useState } from 'react'
import { Outlet, useLocation, useNavigate } from 'react-router-dom'

const App = () => {
  const navigate = useNavigate()
  const { pathname } = useLocation()
  const [currentKeys, setCurrentKeys] = useState('question')
  const [loading, setLoading] = useState(false)

  const { userInfo, picSrc, clearUserData, getUserToken } = useUserStore()

  async function init() {
    try {
      await getUserToken()
      const ticket = new URLSearchParams(window.location.search).get('ticket')
      if (ticket) {
        navigate('/')
      }
    } catch (e) {
      console.log(e)
    } finally {
      setLoading(true)
    }
  }
  
  useEffect(() => {
    init()
  }, [])

  useEffect(() => {
    setCurrentKeys(pathname)
  }, [pathname])
  
  return (
      <div className="app-container h-[100vh]">
        <div className="app-header"></div>
        <div className="app-body">
          {loading && <Outlet />}
        </div>
      </div>
  )
}

三、常用钩子

1、useNavigate

它可以帮助我们在组件中进行路由跳转。

function App() {
  const navigate = useNavigate()
  
  function jumpTo() {
    navigate('/about')
    
    // go(1) 跳转到下一个路由
    navigate(1)
    
    // go(-1) 跳转到上一个路由
    navigate(-1) 
  }
  
}

2、useLocation

它可以帮助我们获取当前路由的信息,返回类似于 window.location 的数据。

function App() {
  const { pathname, host, origin, hash } = useLocation()
  
  return (
      <div>
        <p>当前路由path:{pathname}</p>
      </div>
  )
}

3、useParams

它可以帮助我们获取动态路由参数。

// 跳转页面,路由传参
navigate(`/detail/${id}`)

// 配置动态路由
<Route path="/detail/:id" element={<Detail />}/>

// 获取动态路由参数
import { useParams } from 'react-router-dom'
const { id } = useParams()

4、useQueryParams

它可以帮助我们获取路由查询参数。

// 获取url参数
import { useSearchParams } from 'react-router-dom'
 
const [searchParams, setSearchParams] = useSearchParams()

// 获取参数
searchParams.get('id')

// 判断参数是否存在
searchParams.has('id')

// 同时页面内也可以用set方法来改变路由
setSearchParams({"id":2})

四、常用组件

1、Link

它可以帮助我们在组件中进行声明式导航,作用相当于 a 标签。

import { Link } from 'react-router-dom'

<Link to="/">首页</Link>
<Link to="/about">关于</Link>
<Link to="/detail/135">详情</Link>

2、Navigate

一般用于重定向或鉴权控制。

import { Navigate } from 'react-router-dom'
import NotAuth from '@/pages/403'

// 重定向
<Routes>
  <Route path="/" element={<Film />} />
  <Route path="/about" element={<Cinema />} />
  <Route path="/list" element={<Center />} />
  <Route path="*" element={<Navigate to="/" replace />} />
</Routes>

// 鉴权控制
function App({ children }) {
  const { isLogin } = useUserStore()
  
  return {
    isLogin ? children : <Navigate to="/login" />
  }
}

3、Outlet

它可以帮助我们渲染子路由,类似于 Vue 中的路由插槽。

import { Outlet } from 'react-router-dom'

function App() {
  return (
      <div className="layout">
        <Outlet />
      </div>
  )
}

五、总结

react-router-dom 是一个强大的路由库,结合 React Hook 的使用可以使我们的代码更加简洁和易于维护。通过使用 BrowserRouter、Switch、Route、Link、useHistory、useParams 和 useLocation,我们可以轻松地实现导航、路由跳转、传参和获取参数的功能。


欢迎访问:天问博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SLAM算法与工程实践——相机篇:传统相机使用(2)

SLAM算法与工程实践系列文章 下面是SLAM算法与工程实践系列文章的总链接&#xff0c;本人发表这个系列的文章链接均收录于此 SLAM算法与工程实践系列文章链接 下面是专栏地址&#xff1a; SLAM算法与工程实践系列专栏 文章目录 SLAM算法与工程实践系列文章SLAM算法与工程实践…

从计算机底层深入Golang高并发

从计算机底层深入Golang高并发 1.源码流程架构图 2.源码解读 runtime/proc.go下的newpro() func newproc(fn *funcval) {//计算额外参数的地址argpgp : getg()pc : getcallerpc()//s1使用systemstack调用newproc1 systemstack(func() {newg : newproc1(fn, gp, pc)_p_ : getg…

web前端之正弦波浪动功能、repeat、calc

MENU 效果图htmlstylecalcrepeat 效果图 html <div class"grid"><span class"line"></span><span class"line"></span><span class"line"></span><span class"line"><…

[开源更新] 企业级身份管理和访问管理系统、为数字身份安全赋能

一、系统简介 名称&#xff1a;JNPF权限管理系统 JNPF 权限管理系统可用于管理企业内员工账号、权限、身份认证、应用访问等&#xff0c;可整合部署在本地或云端的内部办公系统、业务系统及第三方 SaaS 系统的所有身份&#xff0c;实现一个账号打通所有应用的服务。其有如下几…

C# OpenVINO 直接读取百度模型实现印章检测

目录 效果 模型信息 项目 代码 下载 其他 C# OpenVINO 直接读取百度模型实现印章检测 效果 模型信息 Inputs ------------------------- name&#xff1a;scale_factor tensor&#xff1a;F32[?, 2] name&#xff1a;image tensor&#xff1a;F32[?, 3, 608, 608] …

oracle aq java jms使用(数据类型为XMLTYPE)

记录一次冷门技术oracle aq的使用 版本 oracle 11g 创建用户 -- 创建用户 create user testaq identified by 123456; grant connect, resource to testaq;-- 创建aq所需要的权限 grant execute on dbms_aq to testaq; grant execute on dbms_aqadm to testaq; begindbms_a…

吴恩达《机器学习》12-2-12-3:大边界的直观理解、大边界分类背后的数学

一、大边界的直观理解 1. 大间距分类器的背景 支持向量机的大间距分类器着眼于构建一个能够在正负样本之间划定最大间距的决策边界。为了理解这一点&#xff0c;首先观察支持向量机的代价函数&#xff0c;其中涉及到正负样本的代价函数cos&#x1d461;1(&#x1d467;)和cos…

【Qt QML入门】Button

Button表示一个推按钮控件&#xff0c;用户可以按下或单击它。 import QtQuick import QtQuick.Window import QtQuick.ControlsWindow {id: winwidth: 800height: 600visible: truetitle: qsTr("Hello World")Button {id: btnwidth: 200height: 100anchors.centerIn…

[笔记] iperf3.1.3源码下载与交叉编译

由于需要测试一款40G网卡&#xff0c;下载了 iperf3.1.3 用于性能测试。 iperf3.1.3 源码下载 可以在 iperf 官网 下载源代码&#xff1a; 交叉编译 需要运行在 aarch64 linux 环境下&#xff0c;所以需要交叉编译。 进入iperf3 目录下&#xff0c;运行 ./configure 脚本…

JavaWeb之前端三件套

前端三件套 HTML1、入门程序2、HTML概念词汇解释3、常见标签3.1 标题标签3.2 段落标签3.3 换行标签3.4 列表标签3.5 超链接标签3.6 多媒体标签3.7 表格标签&#xff08;重点&#xff09;3.8 表单标签(重点)3.9 常见表单项标签(重点)3.10 布局相关标签 CSS1、CSS引入方式2、CSS引…

【Java】线程池的创建

目录 ​编辑 一、什么是线程池 二、创建和使用 导入必要的包&#xff1a; 创建线程池&#xff1a; 提交任务给线程池执行&#xff1a; 自定义Runnable和Callable任务&#xff1a; 关闭线程池&#xff1a; 我的其他博客 一、什么是线程池 在Java中&#xff0c;线程池是…

【Apollo】编译 Apollo 源码

https://github.com/ApolloAuto/apollo/blob/master/docs/01_Installation%20Instructions/apollo_build_and_test_explained.md 查看apollo.sh 的用法 ./apollo.sh --help可以编译整个模块&#xff0c;也可以单独编译某一个子模块./modules 为简单起见&#xff0c;Apollo 6.0…

快速多列查找匹配关键字

实例需求&#xff1a;根据第一列专业名称&#xff0c;在“专业分类指导目录”中&#xff0c;针对三个学历层次&#xff08;研究生、本科生、专科生&#xff09;分别查找对应专业类别&#xff0c;填写在对应位置&#xff0c;即截图中的黄色区域。 需要注意如下两点&#xff1a; …

linux磁盘空间清理

查看磁盘使用情况 查看磁盘分区上可以使用的磁盘空间 $ df -h若要查看文件类型和block&#xff0c;使用下面的命令 $ df -T查看每个文件和目录的磁盘使用空间&#xff0c;也就是文件的大小。 $ sudo du -sh /* $ sudo du -h --max-depth1 /清理旧的 Snap 包版本以释放磁盘空…

内部集成M0内核MCU Sub-1G 高性能低功耗的单片集成收发芯片DP4306F

DP4306F是一款高性能低功耗的单片集成收发机&#xff0c;集成M0核MCU&#xff0c;工作频率可覆盖200MHz~1000MHz&#xff0c;支持230/408/433/470/868/915频段。该芯片集成了射频接收器、射频发射器、频 率综合器、GFSK调制器、GFSK解调器等功能模块。通过SPI接口可以对输出功率…

Rancher中使用promtail+loki+grafna收集k8s日志并展示

Rancher中使用promtail+loki+grafna收集k8s日志并展示 根据应用需求和日志数量级别选择对应的日志收集、过滤和展示方式,当日志量不太大,又想简单集中管理查看日志时,可使用promtail+loki+grafna的方式。本文找那个loki和grafana外置在了k8s集群之外。 1、添加Chart Repo …

浏览器的事件循环机制(Event loop)

事件循环 浏览器的进程模型 何为进程&#xff1f; 程序运行需要有它自己专属的内存空间&#xff0c;可以把这块内存空间简单的理解为进程 每个应用至少有一个进程&#xff0c;进程之间相互独立&#xff0c;即使要通信&#xff0c;也需要双方同意。 何为线程&#xff1f; …

1- Electron 创建项目、初始化项目

Electron官网 Build cross-platform desktop apps with JavaScript, HTML, and CSS | Electron Electron 初始化 初始化项目 - 构造package.json npm init -y 安装Electron模块包 npm i electron -D // 注意&#xff01;如果报错查看node包是否太高 配置启动脚本 {&quo…

UE5:Lumen 框架

1.Lumen渲染流程框架 2.Lumen基本概念 2.1 LumenCard & LumenMeshCards LumenMeshCards&#xff1a;一组带有方向性的模型简化代理&#xff0c;视模型复杂度不同可能包含6个及以上数量的LumenCard&#xff1b;用来提供光照采样的位置和方向。 2.2 LumenCardPage & Lu…

TrustZone之强制隔离

TrustZone有时被称为一个强制执行的保护系统。请求者表示其访问的安全性,而内存系统决定是否允许该访问。内存系统基于何种方式进行检查呢? 在大多数现代系统中,内存系统的检查是由互连完成的。例如,Arm NIC-400允许系统设计人员为每个连接的完成者指定以下内容: • 安全…
最新文章