react-router-dom 6.4版本的尝鲜和总结

1. 版本概述

1.1 版本发布背景

React Router 6.4 版本是继6.0大版本更新之后的又一重要里程碑。此版本发布于2024年,旨在进一步优化开发者体验,提供更加强大和灵活的路由功能。6.4版本在前一版本的基础上,引入了新的数据抽象,增强了导航钩子,使得UI与数据的同步更加容易。

1.2 主要功能与改进

React Router 6.4版本带来了多项新特性和改进,主要包括:

  • 数据抽象:引入了新的数据抽象机制,允许开发者更高效地读取、写入和同步路由数据。
  • 导航钩子增强:导航钩子得到了增强,提供了更多的灵活性和控制力,使得在导航过程中处理数据变得更加简单。
  • 性能优化:6.4版本对性能进行了优化,减少了不必要的渲染,提高了应用的响应速度和流畅度。
  • 更好的类型支持:改进了对TypeScript的支持,使得使用React Router时类型检查更加严格和准确。
  • 文档和示例更新:随着新功能的加入,React Router的官方文档和示例也进行了相应的更新,以帮助开发者更好地理解和使用新特性。

这些改进和特性的加入,使得React Router 6.4成为了构建React应用时的一个强大工具,无论是在功能上还是在性能上都为开发者提供了更多的选择和便利。

2. 安装与配置

2.1 安装命令

React Router 6.4版本的安装可以通过npm或yarn包管理工具进行。首先,确保你的项目中已经安装了React Router 6.4或更高版本。如果尚未安装,可以通过以下命令快速安装:

npm install react-router-dom@latest

或者,如果你使用yarn作为包管理器:

yarn add react-router-dom@latest

2.2 基本配置步骤

安装完成后,你需要按照以下步骤在你的React应用中配置React Router 6.4:

  1. 引入必要的组件:在你的应用入口文件,通常是index.jsApp.js,引入React Router 6.4的核心组件和函数。
import { createBrowserRouter, createRoutesFromElements, RouterProvider, Route, Link } from 'react-router-dom';
  1. 定义路由:使用createBrowserRoutercreateRoutesFromElements定义你的应用路由。你可以将路由定义为对象数组或使用JSX元素。
const router = createBrowserRouter(createRoutesFromElements(<Route path="/" element={<App />}><Route index element={<Home />} /><Route path="about" element={<About />} />{/* 更多路由定义 */}</Route>)
);
  1. 设置路由提供者:在应用的最顶层组件中,使用RouterProvider包裹你的应用,并传入router配置。
function App() {return (<RouterProvider router={router}><Navigation />{/* 其他组件 */}</RouterProvider>);
}
  1. 导航和链接:使用<Link>组件在应用中创建导航链接,使用useNavigate钩子进行编程式导航。
// 使用<Link>组件
<Link to="/about">About</Link>// 使用useNavigate钩子
import { useNavigate } from 'react-router-dom';function SomeComponent() {let navigate = useNavigate();function handleClick() {navigate('/about');}return (<button onClick={handleClick}>Go to About</button>);
}
  1. 数据加载:利用新的数据抽象机制,在路由定义中使用loader函数进行数据预加载。
<Route path="/user/:id" element={<User />} loader={async (args) => {const response = await fetch(`/api/user/${args.params.id}`);return response.json();
}} />

通过遵循上述步骤,你可以顺利地在React应用中集成React Router 6.4,享受到它带来的新特性和改进。

3. 主要组件与用法

3.1 BrowserRouter与HashRouter

React Router 6.4版本中,BrowserRouterHashRouter是两种常用的路由组件,它们提供了不同的路由实现方式。

  • BrowserRouter:使用HTML5的history API来实现路由。它能够感知浏览器的前进和后退操作,支持服务器端渲染(SSR)。BrowserRouter适用于大多数现代Web应用,特别是那些需要SEO优化的场景。
import { BrowserRouter } from 'react-router-dom';const router = createBrowserRouter(createRoutesFromElements(<Route path="/" element={<App />}>{/* 路由定义 */}</Route>
));function App() {return (<BrowserRouter router={router}>{/* 应用组件 */}</BrowserRouter>);
}
  • HashRouter:使用URL的hash部分来实现路由跳转。这种方式不依赖于服务器配置,适用于简单的单页应用,或者那些不支持HTML5 history API的旧浏览器环境。
import { HashRouter } from 'react-router-dom';function App() {return (<HashRouter>{/* 应用组件 */}</HashRouter>);
}

3.2 Routes与Route

RoutesRoute是React Router中定义路由结构的基本组件。

  • Routes:作为路由的容器,包裹所有的Route组件。它负责匹配URL路径,并渲染对应的组件。
import { Routes } from 'react-router-dom';const router = createBrowserRouter(createRoutesFromElements(<Routes><Route path="/" element={<Home />} /><Route path="/about" element={<About />} />{/* 更多路由 */}</Routes>)
);
  • Route:定义具体的路由规则。每个Route组件都需要一个path属性来指定URL路径,以及一个element属性来指定渲染的组件。
import { Route } from 'react-router-dom';// 使用对象数组定义路由
const routes = createRoutesFromElements(<Route path="/" element={<Home />} />,<Route path="/about" element={<About />}>,{/* 更多路由定义 */}
);// 或者使用JSX元素定义路由
<Route path="/" element={<App />}><Route index element={<Home />} /><Route path="about" element={<About />} />{/* 更多路由定义 */}
</Route>

使用RoutesRoute,你可以灵活地定义应用的路由结构,并通过React Router 6.4的新特性,如数据抽象和导航钩子,来增强路由的功能性和用户体验。

4. 导航与路由匹配

4.1 链接导航

链接导航是React Router中最基本的导航方式,通过<Link>组件实现。<Link>组件可以创建一个可点击的链接,当用户点击时,会触发路由的跳转而无需重新加载页面。

  • 基本用法<Link>组件接受一个to属性,该属性指定了目标路由的路径。
import { Link } from 'react-router-dom';function Navbar() {return (<nav><Link to="/">Home</Link `|` <Link to="/about">About</Link></nav>);
}
  • 导航属性:除了to属性,<Link>还支持其他属性,如replace用于替换当前条目而不是向历史添加新条目,state用于传递额外的状态信息给目标路由。
<Link to="/contact" state={{ from: 'about' }}>Contact</Link>
  • 活动链接:使用NavLink可以在路由匹配时添加特殊的样式,以表示当前的活跃路由。
import { NavLink } from 'react-router-dom';function Navigation() {return (<nav><NavLink to="/" activeClassName="active">Home</NavLink><NavLink to="/about" activeClassName="active">About</NavLink></nav>);
}

4.2 编程式导航

编程式导航允许你通过代码来控制路由的跳转,这种方式不依赖于用户的点击事件。React Router 6.4提供了useNavigate钩子来实现编程式导航。

  • 使用useNavigate:在组件内部使用useNavigate可以获取一个导航函数,该函数可以用来跳转到指定的路由。
import { useNavigate } from 'react-router-dom';function Profile() {let navigate = useNavigate();function goToHome() {navigate('/');}return (<button onClick={goToHome}>Go Home</button>);
}
  • 导航选项navigate函数接受第二个参数,一个包含导航选项的对象,例如replace: true可以替换当前历史条目。
navigate('/login', { replace: true });
  • 路由对象导航:除了字符串路径,navigate还可以接受一个路由对象,这在处理动态路由时非常有用。
navigate({pathname: '/user',search: '?query=123',state: { ref: 'nav' },
});
  • 后退和前进:除了跳转到新的路由,useNavigate还可以用来实现后退或前进到历史中的特定条目。
// 后退到上一个路由
navigate(-1);// 前进到下一个路由
navigate(1);

通过链接导航和编程式导航,React Router 6.4为开发者提供了灵活的路由控制方式,无论是响应用户操作还是基于应用逻辑的内部导航,都能轻松实现。

5. 嵌套路由与Outlet

5.1 嵌套路由配置

嵌套路由是React Router 6.4中一个强大的功能,它允许开发者在应用中创建多层次的导航结构。这种结构对于构建复杂的应用界面非常有用,例如具有多个子页面和子组件的仪表板或管理面板。

  • 定义嵌套路由:在React Router 6.4中,你可以使用Route组件的children属性来定义嵌套路由。
const router = createBrowserRouter(createRoutesFromElements(<Route path="/" element={<App />}><Route index element={<Home />} /><Route path="dashboard" element={<Dashboard />}><Route path="overview" element={<Overview />} /><Route path="settings" element={<Settings />} />{/* 更多嵌套路由 */}</Route>{/* 其他路由定义 */}</Route>)
);

在这个例子中,/dashboard路由有两个子路由:/overview/settings,它们都是/dashboard路由的子页面。

  • 配置路由层级:在父路由中使用element属性来指定一个组件,这个组件将作为子路由的容器。
function Dashboard() {return (<div><h1>Dashboard</h1>{/* 使用Outlet来渲染嵌套的子路由 */}<Outlet /></div>);
}

5.2 使用Outlet

Outlet组件是React Router 6.4中用于渲染当前路由匹配的组件的占位符。在嵌套路由的上下文中,Outlet允许你插入子路由的组件。

  • 基本用法:在父组件中,你可以放置一个Outlet组件,它将显示与当前URL匹配的子路由组件。
function App() {return (<RouterProvider router={router}><Navigation /><Outlet /> {/* 这里将显示嵌套的子路由组件 */}</RouterProvider>);
}
  • 动态路由匹配Outlet也支持动态路由。当URL包含动态参数时,Outlet将渲染匹配该参数的路由组件。
<Route path="/user/:id" element={<UserDetail />} />

在这个例子中,如果URL是/user/123Outlet将渲染UserDetail组件,并传递{id: '123'}作为参数。

  • 组合使用:你可以在应用的多个层次上使用Outlet,以创建复杂的嵌套视图。
function Dashboard() {return (<div><Sidebar /><main><Outlet /> {/* 渲染顶层路由 */}</main></div>);
}function UserDetail() {return (<div><h1>User Detail</h1><Outlet /> {/* 可以进一步渲染更深层次的嵌套路由 */}</div>);
}

通过这种方式,Outlet组件提供了一种灵活的方法来组织和渲染嵌套路由,使得开发者能够构建出具有深层导航结构的复杂用户界面。

6. URL参数与查询

6.1 使用useParams钩子

useParams是一个在React Router 6.4中用于访问路由参数的钩子。它允许你在组件中获取URL中的动态参数,例如用户ID或文章的slug。

  • 基本用法:在组件内部使用useParams可以获取当前路由的参数。
import { useParams } from 'react-router-dom';function User() {let params = useParams();console.log(params); // { id: '123' }// 假设URL是/user/123
}
  • 访问特定参数:你可以使用点符号来访问参数对象中的特定属性。
let { id } = useParams();
console.log(id); // '123'
  • 与Route组件结合使用useParams通常与Route组件结合使用,以访问动态路由参数。
<Route path="/user/:id" element={<User />} />

在这个例子中,如果URL是/user/123User组件将通过useParams获取到id参数。

  • 组件订阅:当URL中的参数发生变化时,使用useParams的组件将会自动重新渲染,以反映新的参数值。

6.2 查询参数处理

React Router 6.4也提供了处理查询参数的能力,允许你解析和访问URL中的查询字符串。

  • 解析查询参数:你可以使用useSearchParams钩子和useParams类似的方式来解析查询参数。
import { useSearchParams } from 'react-router-dom';function SearchPage() {let searchParams = useSearchParams();console.log(searchParams); // DOMSearchParams { 'q': 'example' }// 假设URL是/search?q=example
}
  • 获取特定查询值:你可以使用get方法来获取查询参数的特定值。
let query = searchParams.get('q');
console.log(query); // 'example'
  • 修改查询参数:你可以通过修改searchParams对象来更新URL的查询字符串,并触发组件的重新渲染。
searchParams.set('q', 'new query');
  • 查询参数与路由结合:查询参数可以与路由定义结合使用,以实现基于搜索或过滤的功能。
<Route path="/search" element={<SearchPage />} />

在这个例子中,SearchPage组件可以使用useSearchParams来访问和处理URL中的查询参数,例如搜索关键词。通过这种方式,React Router 6.4为构建动态和交互式的Web应用提供了强大的路由参数处理能力。

7. 与React Router v5的比较

7.1 主要差异点

React Router v6相较于v5版本,在API设计和使用方式上进行了一些重要的更新和改进。

  • 组件和函数的导入路径:在v5中,组件和钩子通常从react-router-dom导入,而在v6中,推荐从react-router-dom直接导入所有内容,而不是从react-router

  • 路由配置的变化:v6引入了createBrowserRoutercreateRoutesFromElements函数,用以创建路由器和定义路由。这与v5中的<Switch><Route>组件用法有所不同。

  • 路由渲染方式:v6中使用element属性替代了v5中的componentrender属性,并且<Route>组件不再接受子组件,而是通过element属性传入组件。

  • 导航钩子的增强:v6中的导航钩子提供了更多的灵活性和控制力,允许在导航发生前后执行操作。

  • 数据抽象和加载:v6引入了数据抽象和loader函数,可以在路由级别进行数据预加载,这是v5中没有的特性。

  • useNavigateuseLocation钩子的变更:v6对这些钩子进行了更新,提供了更一致和强大的API。

  • NavLink组件的变化:v6中移除了activeClassName属性,取而代之的是className属性,它接受一个根据路由激活状态返回类名的函数。

  • 类型支持的改进:v6改进了对TypeScript的支持,提供了更严格和准确的类型检查。

7.2 迁移指南

从React Router v5迁移到v6需要考虑以下几个步骤:

  • 更新依赖:首先,需要将react-router-dom的版本更新到v6。

  • API变更:根据v6的API变更,对路由配置代码进行相应的调整,包括路由的创建和渲染方式。

  • 导航钩子:如果项目中使用了useHistorywithRouter,需要迁移到新的useNavigate钩子。

  • NavLink组件:更新NavLink组件的使用,移除activeClassName属性,使用新的className属性。

  • 数据加载:利用v6中的数据抽象和加载特性,对数据加载逻辑进行优化。

  • 类型支持:如果项目使用TypeScript,可以利用v6改进的类型支持进行代码重构,以获得更好的类型检查。

  • 测试和验证:迁移完成后,进行充分的测试以确保路由功能按预期工作。

通过遵循这些迁移指南,可以顺利地将项目从React Router v5升级到v6,同时享受到新版本带来的性能提升和新特性。

如果这篇文章对你有所帮助,欢迎点赞、分享和留言,让更多的人受益。感谢你的细心阅读,如果你发现了任何错误或需要补充的地方,请随时告诉我,我会尽快处理。

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

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

相关文章

力扣372. 超级次方

Problem: 372. 超级次方 文章目录 题目描述思路复杂度Code 题目描述 思路 1.处理数组指数&#xff1a;如下图可以将其转换为一个递归的操作 2.处理 mod 运算:对于模运算我们有公式&#xff1a; ( a b ) % k ( a % k ) ( b % k ) % k (a \times b) \% k (a \% k) \times (b…

Zookeeper原理

Zookeeper监听原理 监听原理详解 &#xff08;1&#xff09;首先要有一个main()线程 &#xff08;2&#xff09;在main线程中创建Zookeeper客户端&#xff0c;这时就会创建两个线程&#xff0c;一个负责网络连接通信(connet)&#xff0c;一个负责监听(listener) 。 &#xf…

使用Qt Creator时遇到错误“Project ERROR: Xcode not set up properly”的解决方案

最近我在macOS上首次安装了Qt 5.5&#xff0c;并使用Qt Creator开发。然而每次启动或打开项目时&#xff0c;都会遇到以下错误提示&#xff1a; Project ERROR: Xcode not set up properly. You may need to confirm the license agreement by running /usr/bin/xcodebuild.然…

PriorityQueue优先队列详解

PriorityQueue优先队列详解 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来详细讲解一下Java中非常重要的数据结构之一——PriorityQueue优先队列。P…

Docker 容器操作命令

文章目录 前言1. 创建并运行容器2. 列出容器3. 停止容器4. 启动已停止的容器5. 重启容器6. 进入容器7. 删除容器8. 查看容器日志9. 导出和导入容器10. 管理网络11. 数据卷操作12. 设置容器自启动 前言 Docker 容器操作是 Docker 使用过程中非常重要的一部分。以下是一些常见的…

记录grid布局属性

grid布局 分为容器和项目元素 容器属性 #container{display:grid;grid-template-columns:100px 100px 100px;/* 1fr 表示比例为占1份 */grid-template-columns:1fr 100px 1fr;/*100px为1列,自动填充,容器宽度不足则换行*/grid-template-columns:repeat(auto-fill,100px);/* …

Unity处理Socket粘包拆包

现在游戏协议的数据格式基本上都是用protobuf协议格式&#xff0c;而protobuf最后会转换为二进制&#xff0c;所以这个例子实现的逻辑的也是二进制的处理。 处理粘包拆包的逻辑主要是在DecodePackage方法中。 using System; using System.Collections; using System.Collecti…

2.XSS-存储型

储存型XSS 或持久型 XSS 交互的数据会被存在在数据库里面,永久性存储,具有很强的稳定性。 在留言板里面进行测试一下是否有做过滤 "<>?&66666点击提交 查看元素代码&#xff0c;已经提交完成&#xff0c;并且没有做任何的过滤措施 接下来写一个javascrip…

select实现超时保护机制

1、使用channel优雅地关闭服务 package mainimport ("context""fmt""net/http""os""os/signal""syscall""time" )func IndexHandler(w http.ResponseWriter, r *http.Request) {if r.Method ! http.Me…

软件工程学系统设计

一、概述 软件设计阶段用比较抽象概括的方式确定目标系统如何完成预定的任务&#xff0c;即确定系统的物理模型。 回答系统 “做什么”。 软件设计是将需求转化为最终产品的唯一途径&#xff0c;是后续开发和维护工作的基础。 1、软件设计过程 从工程管理角度&#xff0c;…

AI 语录(一)

Midjourney创始人谈AI Midjourney创始人关于AI的一些看法给了我新的输入&#xff0c;AI越来越智能化给人了一种脊背发凉的感觉&#xff0c;但是从新水源和冲浪板的角度看&#xff0c;学习驾驭AI和AI共存的方式更加积极也更加合理。 "当计算机比99%的人善于视觉想象的时候…

AI网络爬虫:用deepseek批量提取gptstore.ai上的gpts数据

网站首页&#xff1a;https://gptstore.ai/gpts/categories/finance 翻页规律如下&#xff1a; https://gptstore.ai/_next/data/S9vKNrHo4K82xWjuXpw-O/en/gpts/categories/finance.json?slugfinance&page2 https://gptstore.ai/_next/data/S9vKNrHo4K82xWjuXpw-O/en/g…

Python | Leetcode Python题解之第172题阶乘后的零

题目&#xff1a; 题解&#xff1a; class Solution:def trailingZeroes(self, n: int) -> int:ans 0while n:n // 5ans nreturn ans

目标检测经典算法及其应用

目标检测是计算机视觉领域中的一项核心技术,它旨在让计算机能够像人眼一样识别和定位图像或视频中的物体。具体来说,目标检测不仅需要识别出图像或视频中有哪些对象,还要确定它们在图像或视频中的位置(通常以边界框的形式表示)以及它们的类别。 目标检测的基本框架通常包括…

MySQL与SQLite的区别

MySQL 和 SQLite 是两种常见的关系型数据库管理系统&#xff0c;但它们在设计目标、架构和使用场景上有显著的区别。以下是它们的主要区别&#xff1a; 1. 架构与模式 MySQL&#xff1a; 客户端/服务器模式&#xff1a;MySQL 采用 C/S 架构&#xff0c;数据库服务器运行在一…

【六】【QT开发应用】信号和信号槽的五种写法

第一种写法 第二种写法 第三种写法 第四种写法 第五种写法 完整代码 mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACEclass MainWindow : public QMainWindow …

Golang | Leetcode Golang题解之第172题阶乘后的零

题目&#xff1a; 题解&#xff1a; func trailingZeroes(n int) (ans int) {for n > 0 {n / 5ans n}return }

用全志T113做了块多功能卡片电脑,成本只要60块

FunnyPi-T113是一款基于全志T113-S3/D1S处理器的完全开源多功能开发板&#xff0c;设计FunnyPi最初的目的是想借此T113卡片电脑来满足日常学习&#xff0c;并结合T113高效能和低功耗的特点&#xff0c;来满足像语音助手&#xff0c;智能家居屏幕、桌面摆件屏、博客服务器等嵌入…

React@16.x(35)动画(下)封装动画组件需要注意的问题

目录 1&#xff0c;封装举例2&#xff0c;问题2.1&#xff0c;timeout2.2&#xff0c;配合 SwitchTransition / TransitionGroup 接上篇文章 React动画&#xff08;中&#xff09; 1&#xff0c;封装举例 封装一个渐入渐出效果的动画组件 import { CSSTransition } from &qu…

Maven笔记(更新中)

一、Maven简介 Maven是一款为Java项目构建,依赖管理的工具(软件),使用Maven可以自动化构建,测试,打包和发布项目,大大提高了开发效率和质量 Maven主要作用理解 依赖管理 Maven可以管理项目的依赖,包括自动下载所需依赖库,自动下载依赖所需的依赖并且保证版本没有冲突,依赖版…