前端React Router从入门到进阶实战

React Router 是 React 应用中的一个重要库,它用于实现客户端的路由管理,能够将 URL 路径与 React 组件关联起来,从而实现页面之间的导航。React Router 不会像传统的多页面应用那样重新加载页面,而是通过组件切换来呈现不同的视图,这使得 React 应用能够拥有更高的性能和更流畅的用户体验。

React Router 是 React 生态中最常用的路由库,用于在 React 应用中处理页面的导航和路由。它允许开发者通过 URL 映射到不同的组件,从而创建单页应用(SPA)。React Router 通过声明式方式管理路由的配置,支持嵌套路由、动态路由、路由守卫、重定向等功能。

知识框架

1. React Router 基本概念

1.1 路由与组件的关系

React Router 的核心思想是将 URL 与组件关联,匹配到某个路由时,渲染对应的组件。

  • Route:表示路径与组件的映射关系。
  • Link:在应用中跳转到不同路由的组件。
  • BrowserRouter / HashRouter:为应用提供路由管理,BrowserRouter 使用 HTML5 历史 API,HashRouter 使用哈希值。
1.2 路由的核心组件
  • BrowserRouter / HashRouter:路由容器,包裹整个应用,提供路由的上下文。
  • Route:定义路径与组件的映射关系。
  • Link:用于在应用中进行导航,跳转到指定的路由。
  • Switch(React Router v5及以前)/ Routes(React Router v6及以后):用来确保一次只渲染一个匹配的路由。
1.3 路由的生命周期

React Router 会监听 URL 的变化,当 URL 发生变化时,它会匹配最合适的 Route,并渲染对应的组件。

2. React Router 版本变化

2.1 React Router v5
  • Switch:只有第一个匹配的 Route 会被渲染。Switch 用于包裹路由,并确保在多个路由中,只渲染一个匹配的路由。
  • exact:路由精确匹配,表示路径需要完全匹配才会渲染组件。
2.2 React Router v6
  • Routes:取代了 v5 中的 Switch,用于确保只有一个路由匹配时才会渲染。
  • Route:v6 中的 Route 不再有 exact 属性,所有的路由默认都是精确匹配的。
  • useNavigate:取代了 v5 中的 history.push,用于在函数组件中进行编程式导航。
  • useRoutes:允许通过配置对象定义路由,简化路由配置和动态路由。
  • Outlet:在父路由组件中渲染子路由的占位符。

3.React Router 主要组件

1. Router 组件

React Router 提供了多个 Router 组件来管理路由:

  • <BrowserRouter>:通过 HTML5 的 history API 来保持 UI 和 URL 同步。这是大多数单页应用的推荐使用方式。
  • <HashRouter>:通过 URL 中的 hash 部分(# 后面的部分)来管理路由,适用于不支持 history API 的环境。
  • <MemoryRouter>:使用内存中的路由,适用于非浏览器环境(比如服务器端渲染、React Native)。
import { BrowserRouter as Router } from 'react-router-dom';function App() {return (<Router>{/* 路由定义和组件 */}</Router>);
}
2. Route 组件

<Route> 用于定义路径和渲染的组件。它根据当前路径来判断是否匹配,并渲染对应的组件。

import { Route } from 'react-router-dom';<Route path="/home" component={Home} />
  • path:定义匹配的路径,支持通配符(例如 /post/:id)。
  • component:匹配路径时渲染的组件(React Router v5)。在 v6 中使用 element 属性来渲染组件。
  • renderchildren:可以提供渲染函数来返回动态内容。
3. Link 组件

<Link> 用于在不同的路由之间进行导航。它通过 to 属性指定目标路由。

import { Link } from 'react-router-dom';<Link to="/about">About</Link>
4. Switch / Routes 组件
  • <Switch>:在 React Router v5 中,<Switch> 用于包裹多个 <Route>,确保一次只渲染一个匹配的路由。
  • <Routes>:在 React Router v6 中,<Switch> 被替换为 <Routes>,它同样确保只渲染第一个匹配的路由。
import { Routes, Route } from 'react-router-dom';<Routes><Route path="/" element={<Home />} /><Route path="/about" element={<About />} />
</Routes>
5. useNavigate (React Router v6)

useNavigate 是一个钩子,用于在函数组件中进行编程式导航。

import { useNavigate } from 'react-router-dom';const SomeComponent = () => {const navigate = useNavigate();const goToHome = () => {navigate('/home');};return <button onClick={goToHome}>Go to Home</button>;
};
6. useParams

useParams 是一个钩子,用于在路由中获取动态参数(如路径中的 :id)。

import { useParams } from 'react-router-dom';const Post = () => {const { id } = useParams(); // 获取 URL 参数return <div>Post ID: {id}</div>;
};
7. useLocation

useLocation 可以访问当前 URL 的信息(路径、查询参数等)。

import { useLocation } from 'react-router-dom';const CurrentLocation = () => {const location = useLocation();return <div>Current path: {location.pathname}</div>;
};
8. useMatch

useMatch 用来检查当前的 URL 是否与某个路径匹配,并获取路由参数。

import { useMatch } from 'react-router-dom';const MatchTest = () => {const match = useMatch('/post/:id');return match ? <div>Matched Post ID: {match.params.id}</div> : <div>No match</div>;
};

4.React Router 高级用法

1. 嵌套路由

React Router 支持路由嵌套,父组件的路由可以嵌套显示子路由。通过 <Outlet> 占位符渲染子路由。

import { Routes, Route, Outlet } from 'react-router-dom';const Dashboard = () => (<div><h2>Dashboard</h2><Outlet />  {/* 子路由会渲染在这里 */}</div>
);const Settings = () => <div>Settings Page</div>;function App() {return (<Routes><Route path="/dashboard" element={<Dashboard />}><Route path="settings" element={<Settings />} /></Route></Routes>);
}
2. 路由重定向

React Router 允许通过 <Navigate> 实现路由重定向(在 v6 中取代了 v5 中的 <Redirect>)。

import { Navigate } from 'react-router-dom';<Route path="/old-path" element={<Navigate to="/new-path" />} />
3. 路由守卫

React Router 本身没有内置的路由守卫功能,但可以通过编程方式实现。例如,如果用户没有登录,可以重定向到登录页面。

import { Navigate } from 'react-router-dom';const ProtectedRoute = ({ children }) => {const isAuthenticated = false; // 认证逻辑return isAuthenticated ? children : <Navigate to="/login" />;
};<Routes><Route path="/profile" element={<ProtectedRoute><Profile /></ProtectedRoute>} />
</Routes>
4. 动态加载组件(代码分割)

React Router 可以与 React.lazy()Suspense 一起使用,按需加载组件。

import React, { Suspense, lazy } from 'react';
import { Routes, Route } from 'react-router-dom';const LazyHome = lazy(() => import('./Home'));function App() {return (<Routes><Route path="/" element={<Suspense fallback={<div>Loading...</div>}><LazyHome /></Suspense>} /></Routes>);
}
5. 查询参数

React Router 提供了获取 URL 查询参数的功能,可以通过 useSearchParams 钩子来处理。

import { useSearchParams } from 'react-router-dom';const SearchPage = () => {const [searchParams, setSearchParams] = useSearchParams();const query = searchParams.get('q');  // 获取查询参数return <div>Search query: {query}</div>;
};

5.React Router 配置示例

简单路由配置(React Router v6)
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';const Home = () => <h1>Home Page</h1>;
const About = () => <h1>About Page</h1>;function App() {return (<Router><Routes><Route path="/" element={<Home />} /><Route path="/about" element={<About />} /></Routes></Router>);
}
动态路由配置
import { BrowserRouter as Router, Routes, Route, useParams } from 'react-router-dom';const Post = () => {const { id } = useParams();  // 获取动态路由参数return <h2>Post {id}</h2>;
};function App() {return (<Router><Routes><Route path="/post/:id" element={<Post />} /></Routes></Router>);
}

6. 常用的 React Router 功能实战

3.1 基本用法
import React from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';const Home = () => <div>Home</div>;
const About = () => <div>About</div>;function App() {return (<Router><nav><Link to="/">Home</Link><Link to="/about">About</Link></nav><Switch><Route exact path="/" component={Home} /><Route path="/about" component={About} /></Switch></Router>);
}export default App;
3.2 动态路由
import React from 'react';
import { BrowserRouter as Router, Route, Link, useParams } from 'react-router-dom';const Post = () => {const { id } = useParams(); // 获取动态路由的参数return <div>Post ID: {id}</div>;
};function App() {return (<Router><nav><Link to="/post/1">Post 1</Link><Link to="/post/2">Post 2</Link></nav><Route path="/post/:id" component={Post} /></Router>);
}export default App;
3.3 编程式导航 (React Router v6)
import React from 'react';
import { useNavigate } from 'react-router-dom';const Home = () => {const navigate = useNavigate();const handleClick = () => {navigate('/about');};return (<div><h1>Home</h1><button onClick={handleClick}>Go to About</button></div>);
};export default Home;
3.4 嵌套路由
import React from 'react';
import { BrowserRouter as Router, Route, Link, Outlet } from 'react-router-dom';const Dashboard = () => (<div><h2>Dashboard</h2><nav><Link to="settings">Settings</Link></nav><Outlet /> {/* 渲染嵌套路由的占位符 */}</div>
);const Settings = () => <div>Settings Page</div>;function App() {return (<Router><Route path="dashboard" element={<Dashboard />}><Route path="settings" element={<Settings />} /></Route></Router>);
}export default App;

7. 高级用法实战

4.1 路由重定向
  • Redirect(v5)/ Navigate(v6)

v5

import { Redirect } from 'react-router-dom';// 重定向到首页
<Route path="/old-path"><Redirect to="/" />
</Route>

v6

import { Navigate } from 'react-router-dom';<Route path="/old-path" element={<Navigate to="/" />} />
4.2 路由守卫(保护路由)

React Router 本身不提供守卫功能,但可以通过编程方式进行实现,例如根据用户的认证状态来决定是否跳转到登录页。

import { Navigate } from 'react-router-dom';const ProtectedRoute = ({ element, ...rest }) => {const isAuthenticated = false; // 用户是否认证return isAuthenticated ? element : <Navigate to="/login" />;
};// 使用
<Route path="/profile" element={<ProtectedRoute element={<Profile />} />} />
4.3 通过 useLocation 获取当前 URL
import { useLocation } from 'react-router-dom';const CurrentLocation = () => {const location = useLocation();return <div>Current URL: {location.pathname}</div>;
};
4.4 动态加载组件

通过 React.lazySuspense 实现按需加载。

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';const LazyHome = lazy(() => import('./Home'));function App() {return (<Router><Suspense fallback={<div>Loading...</div>}><Route path="/" component={LazyHome} /></Suspense></Router>);
}

8. React Router 底层核心原理

8.1 核心原理

  • 路由监听: 通过 window.historywindow.location.hash 监听 URL 的变化。
  • 匹配规则: 使用 path-to-regexp 库将路径转换为正则表达式,匹配当前 URL。
  • 渲染更新: 匹配的路由组件通过 React 的状态更新机制触发重新渲染。

8.2 关键步骤

  1. 路由定义时,存储路径与组件的映射关系。
  2. URL 变化时,根据路径规则找到对应组件。
  3. 使用 React 渲染匹配的组件。

React Router 底层的核心原理围绕着以下几个关键点:

  • 路由匹配:通过 URL 路径与路由配置进行匹配,决定渲染哪个组件。
  • history API:通过监听浏览器的历史记录来管理路由变化。
  • 虚拟 DOM 更新:通过 React 的更新机制,在路由变化时高效

地更新组件。

  • 嵌套路由:通过 Outlet 组件来支持父子路由的嵌套渲染。
  • 优化渲染:只重新渲染需要更新的组件,提升性能。

理解这些底层原理,能够帮助你更好地使用 React Router,并且在遇到复杂路由需求时,能够更灵活地调整和优化路由配置。

总结

React Router 是构建 React 应用的路由管理工具,具有强大的功能,如支持动态路由、嵌套路由、导航守卫、代码分割等。理解其核心概念及高级用法,可以帮助开发者更高效地构建和维护复杂的 React 应用。

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

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

相关文章

K-means算法在无监督学习中的应用

K-means算法在无监督学习中的应用 K-means算法是一种典型的无监督学习算法&#xff0c;广泛用于聚类分析。在无监督学习中&#xff0c;模型并不依赖于标签数据&#xff0c;而是根据输入数据的特征进行分组。K-means的目标是将数据集分成K个簇&#xff0c;使得同一簇内的数据点…

Linux 35.6 + JetPack v5.1.4之 pytorch升级

Linux 35.6 JetPack v5.1.4之 pytorch升级 1. 源由2. 升级步骤1&#xff1a;获取二进制版本步骤2&#xff1a;安装二进制版本步骤3&#xff1a;获取torchvision步骤4&#xff1a;安装torchvision步骤5&#xff1a;检查安装版本 3. 使用4. 补充4.1 torchvision版本问题4.2 支持…

Spring——自动装配

假设一个场景&#xff1a; 一个人&#xff08;Person&#xff09;有一条狗&#xff08;Dog&#xff09;和一只猫(Cat)&#xff0c;狗和猫都会叫&#xff0c;狗叫是“汪汪”&#xff0c;猫叫是“喵喵”&#xff0c;同时人还有一个自己的名字。 将上述场景 抽象出三个实体类&…

TCP与DNS的报文分析

场景拓扑&#xff1a; 核心路由配置&#xff1a; 上&#xff08;DNS&#xff09;&#xff1a;10.1.1.1/24 下(WEB)&#xff1a;20.1.1.1/24 左&#xff08;client&#xff09;&#xff1a;192.168.0.1/24 右(PC3)&#xff1a;192.168.1.1/24Clint2配置&a…

PWR-STM32电源控制

一、原理 睡眠模式不响应其他操作&#xff0c;比如烧写程序&#xff0c;烧写时按住复位键松手即可下载&#xff0c;在禁用JTAG也可如此烧写程序。 对于低功耗模式可以通过RTC唤醒、外部中断唤醒、中断唤醒。 1、电源框图&#xff1a; VDDA主要负责模拟部分的供电、Vref和Vref-…

WebSocket 测试入门篇

Websocket 是一种用于 H5 浏览器的实时通讯协议&#xff0c;可以做到数据的实时推送&#xff0c;可适用于广泛的工作环境&#xff0c;例如客服系统、物联网数据传输系统&#xff0c; 基础介绍 我们平常接触最多的是 http 协议的接口&#xff0c;http 协议是请求与响应的模式&…

基于机器学习的故障诊断(入门向)

一、原始信号的特征提取 1.EMD经验模态分解的作用 信号分析&#xff1a;EMD可以将信号分解为多个IMFs&#xff0c;每个IMF代表信号中的一个特定频率和幅度调制的成分。这使得EMD能够提供对信号的时频特征进行分析的能力&#xff08;特征提取用到的&#xff09;。信号去噪&…

【算法刷题】leetcode hot 100 双指针

文章目录 283. 移动零11. 盛最多水的容器15. 三数之和42. 接雨水 283. 移动零 https://leetcode.cn/problems/move-zeroes/description/?envTypestudy-plan-v2&envIdtop-100-liked 解法一&#xff1a; 找到第一个等于0的下标&#xff0c;然后继续向右找到第一个不等于0的…

【蓝桥杯选拔赛真题60】C++寻宝石 第十四届蓝桥杯青少年创意编程大赛 算法思维 C++编程选拔赛真题解

目录 C++寻宝石 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 五、运行结果 六、考点分析 七、推荐资料 C++寻宝石 第十四届蓝桥杯青少年创意编程大赛C++选拔赛真题 一、题目要求 1、编程实现 有N(1<N<100)个盒子排成一排,每个盒子都放…

Nginx入门笔记

Nginx入门笔记 一、Nginx基本概念二、代理1、正向代理2、反向代理 三、准备工作1、CentOS 7安装nginx&#xff08;1&#xff09;. 安装必要的依赖&#xff08;2&#xff09;下载nginx&#xff08;3&#xff09;编译安装&#xff08;4&#xff09;编译并安装 Nginx(5)启动nginx …

重塑视频创作的格局!ComfyUI-Mochi本地部署教程

一、介绍 mochi是近期Genmo公司开源的先进视频生成模型&#xff0c;具有高保真运动和强大的提示遵循性。此模型的发布极大的缩小了闭源和开源视频生成系统之间的差距。 目前&#xff0c;视频生成模型与现实之间存在巨大差距。其中最影响视频生成的两个关键功能也就是运动质量和…

el-table自定义按钮控制扩展expand

需求&#xff1a;自定义按钮实现表格扩展内容的展开和收起&#xff0c;实现如下&#xff1a; 将type“expand”的表格列的宽度设置为width"1"&#xff0c;让该操作列不展示出来&#xff0c;然后通过ref动态调用组件的内部方法toggleRowExpansion(row, row.expanded)控…

Ubuntu 22.04 英伟达开发环境 CUDA 12.4 | cuDNN 9.0.0 | TensorRT 10.1 版本安装指南

NVIDIA 驱动安装 前置 笔者近期重整服务器&#xff0c;计划重新安装操作系统并配置新的开发环境。服务器的主要配置如下&#xff1a; Dell PowerEdge R730 Intel Xeon E5-2630v3 x2 64GB ECC DDR4 NVIDIA GeForce RTX 2080 Ti Rev. A Ubuntu 22.04.5 LTS x86_64 (No Desktop…

数据结构-栈、队列和数组

栈 栈的定义 栈是只允许在一端进行插入或删除操作的线性表。首先栈式一种线性表&#xff0c;但限定这种线性表只能在某一端进行插入和删除操作&#xff0c;如图所示。 栈包括&#xff1a; 栈顶&#xff08;Top&#xff09;。允许进入插入删除的那一端。 栈底&#xff08;Butt…

Mysql快速列出来所有列信息

文章目录 需求描述实现思路1、如何查表信息2、如何取字段描述信息3、如何将列信息一行展示4、拼接最终结果 需求描述 如何将MySQL数据库中指定表【tb_order】的所有字段都展示出来&#xff0c;以备注中的中文名为列名。 实现思路 最终展示效果&#xff0c;即拼接出可执行执行…

LLM大模型实践10-聊天机器人

大型语言模型带给我们的激动人心的一种可能性是&#xff0c;我们可以通过它构建定制的聊天机器人 &#xff08;Chatbot&#xff09;&#xff0c;而且只需很少的工作量。在这一章节的探索中&#xff0c;我们将带你了解如何利用会话形式&#xff0c;与具 有个性化特性&#xff08…

用python实现烟花代码,完整代码拿走不谢

有时候用python实现一些有趣的代码&#xff0c;既有趣&#xff0c;又能提升知识 使用Python实现动态烟花代码 效果如下&#xff1a; 不废话&#xff0c;直接上代码&#xff1a; import pygame from random import randint, uniform, choice import mathvector pygame.math…

【Java项目】基于SpringBoot的【校园交友系统】

【Java项目】基于SpringBoot的【校园交友系统】 技术简介&#xff1a;系统软件架构选择B/S模式、SpringBoot框架、java技术和MySQL数据库等&#xff0c;总体功能模块运用自顶向下的分层思想。 系统简介&#xff1a;系统主要包括管理员和用户。 (a) 管理员的功能主要有首页、个人…

使用强化学习训练神经网络玩俄罗斯方块

一、说明 在 2024 年暑假假期期间&#xff0c;Tim学习并应用了Q-Learning &#xff08;一种强化学习形式&#xff09;来训练神经网络玩简化版的俄罗斯方块游戏。在本文中&#xff0c;我将详细介绍我是如何做到这一点的。我希望这对任何有兴趣将强化学习应用于新领域的人有所帮助…

大湾区经济网与澳门红刊杂志社签署战略合作

大湾区经济网澳门1月9日电&#xff08;王强&#xff09;2025年1月9日&#xff0c;在粤港澳大湾区建设稳步推进的时代背景下&#xff0c;大湾区经济网与澳门红刊杂志社成功签署了合作协议&#xff0c;标志着双方在媒体战略合作领域迈出了坚实的一步&#xff0c;将共同为粤港澳大…