React Router初学者入门指南(2023版)

1ddeeff44f57a299ef3e874397ddd090.jpeg

React Router,简单来说,是一个帮助处理React应用程序中导航和路由的库。它是用于管理React中路由的最流行的路由工具。如果你对路由的概念不熟悉,可以将其视为在网站的不同部分之间导航的过程。例如,当你进入网站的“联系我们”部分时,你已经成功进行了一次路由过程。本文将为您提供有关React Router的所有细节,以便您可以充分利用它。

如果你对React Router还不熟悉,你可能习惯使用普通的链接(a标签)在你的应用程序中进行导航。然而,当你想在导航时保留应用程序的当前状态时,就会出现问题。不幸的是,普通的链接通常会触发页面刷新来显示组件,从而破坏用户体验。这就是React Router的用武之地。

React Router允许您在应用程序中定义不同的路由,并将它们链接到各自的组件,而无需重新加载页面。这种方法使得React Router能够轻松更新页面上的内容,并使网站感觉像一个原生应用程序。

使用React Router还有其他好处,比如创建复杂的导航、无缝的页面导航结构以及对动态URL的支持。

设置环境

要理解React Router的工作原理,最好的方法之一是构建一个简单的网站。因此,让我们构建一个小型的历史网站,不要太复杂。

所以,让我们准备好一切开始使用React Router所需的东西。

安装React:有几种方法可以做到这一点,但让我们选择最简单的方法:create-react-app(CRA)。通过代码编辑器终端安装React,运行以下命令:

npx create-react-app history-app

然后,通过运行cd history-app导航到创建的React应用程序。

  • 安装React Router:要在React网站中安装react-router包,请在终端中运行以下命令:

npm install react-router-dom

这个命令允许你安装React Router,一个必要的包。

完成后,您可以通过运行npm start来启动React应用程序。就是这样!React和React Router已经准备好使用了。

让我们添加一些React组件,以便在历史应用程序上获得一些虚拟内容。您只需将其复制并粘贴到App.js中,即默认的应用程序组件。

export default function App() {return (<><Home /></>);
}function Home() {return (<div><h1>The Paradise of History</h1><p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil verolaudantium repella</p></div>);
}function Eras() {return (<div><h1>The Eras of Time</h1><ul><li><a href="/">Medieval</a></li><li><a href="/">Digital</a></li></ul></div>);
}

运行后的效果

37f9ae0792cbd5dc6415ff58a71b4cc7.png

理解路由概念

在我们继续之前,让我们快速了解一些React Router中的关键概念:

History Stack:React Router智能地使用HTML5 History API来跟踪用户的导航历史。当用户访问一个新的URL时,React Router将该URL推送到历史堆栈中。当用户导航到其他URL时,它们也会被推送到堆栈中。这就是React Router在不刷新页面的情况下来回导航路由的方式。

Location:这指的是在浏览网站时当前所在的URL。它是历史堆栈中的顶级URL,以及React Router如何动态更改显示的内容以匹配正确的URL。

在一些浏览器中,比如Chrome,你可以点击并长按“返回”按钮来查看历史记录中所有的URL列表。

浏览器路由器及其用途

众所周知,React使用组件和钩子,React Router也是如此。而React Router提供的一个关键组件是。

就像body元素是网站的骨干一样,BrowserRouter 对于 React Router 也是如此。它为网站内所有可能的路由提供了基础。

注意:BrowserRouter使用HTML5 History API来操作浏览器的URL,并将其与当前显示的页面保持同步。

BrowserRouter可以放置在应用程序的任何位置,但通常情况下,您会希望将BrowserRouter放置在组件树的顶部,以包裹整个应用程序的组件。

现在,回到构建我们简单的历史网站的过程中。为了实现BrowserRouter,将整个App组件包裹在其中。要做到这一点,请转到index.js文件:

import { BrowserRouter } from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<React.StrictMode><BrowserRouter><App /></BrowserRouter></React.StrictMode>
);

通过 <BrowserRouter /> App 组件,路由功能在 App 组件中的所有组件中都可用。

关于BrowserRouter的内容就这些了,我们继续吧。

值得注意的是,还有其他类似的组件可用,比如 MemoryRouter、StaticRouter 等等。

使用 Routes 和 Route

要完全掌握React Router中的 Routes 组件的作用,首先我们需要了解 Route 的作用。

Route

简单来说, Route 定义了一个特定的URL路径,并指向在访问该URL路径时应该渲染的组件。

路由组件有两个主要属性:

Path:此属性接受一个字符串,用于指定 Route 的路径。例如,如果有一个 Route ,其 path 设置为 "/eras" ,每当URL变为
https://historyApp.com/eras 时,将触发此 Route 。

Element:当 path 属性中的路径被访问时,该属性被分配给要渲染的React组件。因此,如果访问 /eras 路径,则 <Eras /> 组件将在页面上呈现。

这里是一个代码示例:

<Route path='/eras' element={<Eras />} />

Routes

Routes 是 Route 组件的容器组件。它负责检查当前URL位置,并将其与子 Route 组件中指定的路径进行比较,以找到匹配项。

在 Routes 内,您可以嵌套所有的 Route 组件,然后在浏览网站时, Routes 会获取当前的URL,并将其与每个子路由组件进行匹配,以找到与之对应的最佳组件。

因此,在历史应用程序中设置 Routes 和 Route 的步骤如下:

import { Routes, Route } from 'react-router-dom';export default function App() {return (<Routes><Route path="/" element={<Home />} /><Route path="/eras" element={<Eras />} /></Routes>);
}

这段代码中:

  • 首先从 react-router-dom 包中导入 Routes 和 Route 组件。

  • 然后,在 App 组件内部, Routes 组件限制了不同的 Route 组件。

  • 第一个路由的路径设置为("/"),当访问时将渲染 Home 组件。这个默认路由将始终在访问根URL时渲染。

  • 该 /eras 路由与 Eras 组件相关联。这意味着每当URL路径与 /eras 匹配时,将显示 <Eras /> 内容。

当您在地址栏中的根URL后添加 /eras 时,React Router使用 Routes 组件来匹配具有路径设置为 /eras 的确切 Route 。一旦找到,将渲染在匹配的 Route 的 element 属性中定义的组件;在这种情况下,是 <Eras /> 组件。

1b0292b8d1ac1b4a3f5ac4037d252a51.gif

404 页面

404错误是一个HTTP状态码,当请求的资源或页面无法找到时会显示出来。这可能发生在用户输入了一个不存在的URL时。

React Router 包含了一种处理 404 错误的方式,当访问一个未定义的网址时,会渲染一个自定义组件。

要处理React Router中的404错误,请创建一个 route ,将其 path 属性设置为 * ,并将其 element 属性设置为应该呈现的错误组件。

可以这样实施:

首先,让我们创建一个错误404组件

function Error404() {return (<div><h1>404 — Page Not Found</h1><a href="/">Take me back!</a></div>);
}

然后创建一个 route 来渲染 <Error404 />.

export default function App() {return (<Routes><Route path="/" element={<Home />} /><Route path="/eras" element={<Eras />} />{/* 404 page */}<Route path="*" element={<Error404 />} /></Routes>);
}

有了这个设置,每当访问一个不存在的URL时,React Router会自动使用 route 组件,并将 path 设置为 * ,然后渲染其元素,即 Error404 组件。

8591066c72ad6792b9d9cbc14c6edc43.gif

现在,我们可以放心地确保网站能够处理任何意外的URL。

路由之间的连接

到目前为止,我们只讨论了如何通过手动在地址栏中输入URL来访问路由。然而,这种方式并不理想,因为用户必须记住每个页面的确切URL才能访问。

a 标签通常用于解决这个问题,但它有一些限制。为了绕过这些限制,React Router使用 Link 组件。

在React Router中, Link 是路由导航的主要方式。链接组件在底层使用 a 标签,但通过阻止默认页面重新加载来增强它。相反, Link 将其 to 属性中的URL推送到历史堆栈,然后 routes 组件找到具有相同URL的匹配 route 并显示相关组件。

React Router使用 Link 组件而不是 a 标签,因为 Link 被设计用于防止页面重新加载,保留应用程序状态,并在路由之间提供无缝导航。

这是在历史网站中使用 Link 的方法。前往 App.js 并创建一个导航组件:

import { Link } from "react-router-dom";function Nav() {return (<ul className='nav'><li><Link to='/'>Home</NavLink></li><li><Link to='/eras'>Eras</NavLink></li></ul>);
}

首先从 react-router-dom 导入 Link 组件。然后,创建一个功能组件 Nav ,用作历史网站的导航。

这个 Nav 组件遵循了典型导航菜单的结构;只是使用了 Link 组件而不是 a 标签。

每个 <Link /> 都有一个特定的路径分配给 to 属性;这为 Link 设置了目标路由。因此,当点击任何这些链接时,React Router会从 to 属性获取URL,匹配正确的 route 路径,并渲染指定的组件。

由于 Nav 组件应该在所有页面上可见,让我们将其放置在 App 组件的顶部:

export default function App() {return (<><Nav /><Routes><Route path='/' element={<Home />} /><Route path='/eras' element={<Eras />} /><Route path='*' element={<Error404 />} /></Routes></>);
}

我们还可以给它添加一些简单的样式来增加吸引力:App.css

a {text-decoration: none;color: inherit;
}
a:hover {color: #e32a30;
}.nav {list-style: none;display: flex;width: 500px;justify-content: space-around;align-items: center;font-size: 1.1rem;font-weight: bold;
}

e0357af9a10003a8562b2632fa9be1ea.gif

NavLink 与 Link 的不同

React Router有一个叫做 NavLink 的组件。它类似于 Link ,但主要用于处理菜单导航链接,不同于 Link 组件,后者可用于任何类型的链接。

NavLink 和 Link 之间的主要区别是 NavLink 能够检测自身是否处于活动状态。当 NavLink 检测到自身处于活动状态时,默认会给其组件添加一个 active 类。

由于历史网站中存在导航菜单,让我们将 Link 组件更新为 NavLink

import { Link, NavLink } from "react-router-dom";function Nav() {return (<ul className='nav'><li><NavLink to='/'>Home</NavLink></li><li><NavLink to='/eras'>Eras</NavLink></li></ul>);
}

active 类可以使用CSS进行自定义。前往 App.css 进行修改:

.active {color: #e32a30;
}

5a02b4c016099f81ea45831579d1471e.gif

总的来说, NavLink 在创建导航菜单链接时比 Link 组件更强大。

嵌套路由

在React Router中,嵌套可以被视为在路由之间建立父子连接。这可以用来组织共享相同URL路径的路由。

嵌套路由使用一个 Route 组件作为父路由,另一个 Route 组件用于定义父路由内的子路由。因此,只有在父路由上时才能渲染子路由。

在历史网站上,可以在时代部分找到“中世纪(Medieval)”和“数字化(Digital)”这两个可用的时代类别。因此,要访问这些时代的详细信息,我们可以将它们嵌套在 /eras 路径中。

让我们将这个功能添加到历史网站上:

创建“Medieval”和“Digital”组件:

function MedievalEra() {return (<div><hr /><h3>The Medieval Era</h3><p>Lorem ipsum dolor sit amet.</p></div>);
}function DigitalEra() {return (<div><hr /><h3>The Digital Era</h3><p>Lorem ipsum dolor sit amet.</p></div>);
}

转到 App 组件,并在 /eras 路由内创建嵌套路由:

export default function App() {return (<><Nav /><Routes><Route path="/" element={<Home />} /><Route path="/eras" element={<Eras />}><Route path="medieval" element={<MedievalEra />} /><Route path="digital" element={<DigitalEra />} /></Route><Route path="*" element={<Error404 />} /></Routes></>);
}

此时,导航到 /eras/medieval 或 /eras/digital 应该分别呈现 <MedievalEra /> 和 <DigitalEra /> 组件。然而,它不会按预期呈现。

这是因为React Router不知道如何放置这些嵌套组件。为了解决这个问题,React Router提供了一个名为 Outlet 的组件,可以明确指出嵌套路由组件应该放置在哪里。

导入 Outlet 组件:

import { Outlet } from "react-router-dom";

将 Outlet 组件放置在 Eras 组件内部:

function Eras() {return (<div><h1>The Eras of Time</h1><ul><li><Link to="medieval">Medieval</Link></li><li><Link to="digital">Digital</Link></li></ul><Outlet /></div>);
}

在这段代码中,之前使用的 a 标签已被替换为 Link 组件,并将相应的路径放置在 to 属性中。

在此之后, <Outlet /> 组件将被放置在下方,因为这是嵌套路由组件将被渲染的位置。

e748c3b14ec06d5d9878af6c798638ec.gif

嵌套路由有各种用途,比如层次化组织路由、代码效率、提高性能等。

动态路由与useParams

动态路由是一个概念,它允许您创建不是硬编码的路由,而是根据用户操作或数据生成的路由。

React Router使用 Route 组件和 useParams 钩子来处理动态路由。

设置动态路由时,在 route 组件的 path 属性中使用占位符(用冒号 : 表示)。

就像这样:

<Route path="/eras/:type" element={<EraType />} />

这里,对于 Route 的占位符是 : type ,它表示 type 参数的值将会动态生成。

React Router 提供了一个叫做 useParams 的钩子,用于有效处理动态路由。

基本上, useParams hook 返回一个包含来自 Route 组件的动态值的对象,该值可以在负责渲染动态内容的组件中使用。

让我们看看它是如何工作的:

import { useParams } from "react-router-dom";function EraType() {const { type } = useParams();return (<div><hr /><h3>The {type} Era</h3></div>);
}

现在更新在 /eras 中找到的路由,以包括动态路由:

export default function App() {return (<><Nav /><Routes><Route path='/' element={<Home />} /><Route path='/eras' element={<Eras />}><Route path='medieval' element={<MedievalEra />} /><Route path='digital' element={<DigitalEra />} />{/* Dynamic route */}<Route path=':type' element={<EraType />} /></Route><Route path='*' element={<Error404 />} /></Routes></>);
}

有了这个动态 Route ,当你在 /eras 路由内导航时,像 /eras/ancient 这样。值“ancient”是动态路径,并且可以通过从 useParams 提取的 type 变量进行访问。

由于嵌套的路由结构, <Eras /> 组件内的 <EraType /> 被渲染出来。

38dd725c7deb05edb896009ae13d4dff.gif

这只是 useParams 的一个基本用例;这个钩子可以用于其他方式,比如从API中获取类似的动态数据。

使用useRoutes钩子

React Router 提供的另一个钩子是 useRoutes 钩子。

这个钩子只是React Router中用于结构化 Routes 和 Route 的另一种方式。它的工作原理是:不使用React组件(JSX)的形式,而是使用JavaScript对象。

在 App.js 中,这是我们如何构建 Routes 和 Route 组件的结构:

export default function App() {return (<><Nav /><Routes><Route path='/' element={<Home />} /><Route path='/eras' element={<Eras />}><Route path='medieval' element={<MedievalEra />} /><Route path='digital' element={<DigitalEra />} /><Route path=':type' element={<EraType />} /></Route><Route path='*' element={<Error404 />} /></Routes></>);
}

现在,通过使用 useRoutes 钩子,代码可以重构如下:

import { useRoutes } from 'react-router-dom';export default function App() {const routes = useRoutes([{path: "/",element: <Home />,},{path: "/eras",element: <Eras />,children: [{path: "medieval",element: <MedievalEra />,},{path: "digital",element: <DigitalEra />,},{path: ":type",element: <EraType />,},],},{path: "*",element: <Error404 />,},]);return (<><Nav />{routes}</>);
}

useRoutes 钩子从 react-router-dom 导入。然后,一个路由对象数组被传递给 useRoutes 。每个路由对象都有一个 path 和 element 属性,用于指定路径和在路由匹配时应该渲染的组件。

所以,在 useRoutes 钩子或 Routes 和 Route 组件之间的选择归结为个人偏好。选择最适合你风格的那个。

结束

总之,学习React Router是React开发者应该迈出的重要一步。通过使用这个工具,在应用中管理路由导航和创建良好结构化的路由系统变得轻而易举。

由于文章内容篇幅有限,今天的内容就分享到这里,文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。

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

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

相关文章

从AlexNet到chatGPT的演进过程

一、演进 AlexNet&#xff08;2012&#xff09;&#xff1a; AlexNet是深度学习领域的重要突破&#xff0c;包括5个卷积层和3个全连接层。使用ReLU激活函数和Dropout正则化&#xff0c;获得了ImageNet图像分类比赛的胜利。引入了GPU加速训练&#xff0c;大幅提高了深度神经网络…

Android系统的特性

目录 Android系统的特性 1. 显示布局 2. 数据存储 3. 网络 4. 信息 5. 浏览器 6. 编程语言支持 7. 媒体支持 8. 流媒体支持 9. 硬件支持 10. 多点触控 11.蓝牙 12. 多任务处理 13. 语音功能 14.无线共享功能 15. 截图功能 16. 跨平台 17. 应用程序的安全机制…

Flutter笔记:完全基于Flutter绘图技术绘制一个精美的Dash图标(上)

Flutter笔记 完全基于Flutter绘图技术绘制一个精美的Dart语言吉祥物Dash&#xff08;上&#xff09; 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://…

No authorization token was found

今天遇到了一个问题&#xff0c;我把前后端逻辑都理了一遍&#xff0c;开始怀疑后端&#xff0c;后端肯定没错了&#xff0c;把前端理了一遍&#xff0c;ok前后端没错&#xff0c;我错。登录哪里需要的token&#xff1f;&#xff1f;&#xff1f;&#xff1f;把我搞懵逼了。 测…

npm start启动的是什么

npm start 命令是在一个 Node.js 项目中执行的一个自定义命令&#xff0c;用于启动该项目。该命令是在 package.json 文件中定义的&#xff0c;通常被用于启动一个 Web 应用程序或服务。 具体来说&#xff0c;当在项目目录下执行 npm start 命令时&#xff0c;npm 将会在该项目…

[红蓝攻防]MDOG(全新UI重制版)为Xss跨站而生,数据共享,表单劫持,URL重定向

说明 功能Cookie窃取表单劫持(钓鱼账密)重定向流量劫持多平台数据推送钉钉数据推送 运行窗口 ./dist目录下已生成exe文件,双击打开 Cookie窃取 点击运行服务,复制以上的payload,payload怎么变形那么你可已去混淆 payload在页面执行 受害者访问存在xss漏洞的页面时受到攻击,…

Capacitor 打包 h5 到 Android 应用,uniapp https http net::ERR_CLEARTEXT_NOT_PERMITTED

Capacitor 打包 h5 到 Android 应用&#xff0c;uniapp https http net::ERR_CLEARTEXT_NOT_PERMITTED capacitor 官网&#xff1a; https://capacitorjs.com/docs/ 项目上需要做一个 app&#xff0c;而这个 app 是用 uniapp 做的&#xff0c;里面用到了一个依赖 dom 的库&…

项目管理概论:什么是项目、项目管理的重要性、成功的标准包含什么以及相关笔记

本文摘要 按照惯例,咱们开篇先介绍一下项目概论中的相关概念,然后记录一下这里面的关键知识点和重点笔记。 这些知识点和笔记源自《信息系统项目管理师教程》(第4版)、往年概念方向的真题甚至题干(有时候题目就是知识点 👻)。 本文会不断的更新和补充,比如一些晦涩的概念…

目标检测YOLO实战应用案例100讲-基于无人机图像的房屋目标检测

目录 前言 国内外研究现状 房屋建筑检测的研究现状 深度学习的研究现状

Android官方ShapeableImageView描边/圆形/圆角图,xml布局实现

Android官方ShapeableImageView描边/圆形/圆角图&#xff0c;xml布局实现 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.…

【理论知识:Window Aggregation】flink 窗口聚合功能概述:两种窗口聚合模式的使用例子、功能说明

文章目录 一. Windowing TVFs1. 三种类型聚合的例子2. GROUPING SETS子句语法 ing2.1.ROLLUP2.2. CUBE 3. Selecting Group Window Start and End Timestamps4. 级联窗口聚合&#xff08;Cascading Window Aggregation&#xff09; 二. Group Window Aggregation1. Group Windo…

IDEA新建maven项目,使用mybatis操作数据库完整过程

IDEA新建maven项目&#xff0c;使用mybatis操作数据库完整过程 一、IDEA新建maven项目二、配置mybatis三、创建表对应实体类四、创建mapper接口五、使用mybatis操作数据库 前提&#xff1a; 这个教程是在maven项目中使用mybatis进行数据库操作&#xff0c;不是在spring boot项目…

力扣 88. 合并两个有序数组

目录 1.解题思路2.代码实现 1.解题思路 另开辟一个大小为mn的数组再利用双指针判断两个指针的大小&#xff0c;将小值赋给数组上并给该数组的下标加一和该指针加一&#xff0c;其次&#xff0c;要判断两个数组是否已经被拷贝完&#xff0c;如果其中一个已经到头&#xff0c;那…

牛客小白月赛80 D一种因子游戏

D一种因子游戏 思路&#xff1a;我们考虑&#xff0c;对于A数组中的每个数&#xff0c;我们考虑B数组中是否存在某个对应的数字能和其匹配&#xff0c;即 g c d gcd gcd等于1。由此想到二分图最大匹配&#xff0c;算出最大匹配数然后判断即可。 #include<bits/stdc.h>u…

接口自动化测试工具,Postman使用详解

一、概念 1、Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件&#xff0c;Postman分为Postman native app和Postman Chrome app两个版本。目前Chrome app已经停止维护&#xff0c;官方也不推荐使用该版本。 2、官网下载地址&#xff1a;http://www.getpostman…

071:mapboxGL上传含shp的zip文件,在map上解析显示图形

第071个 点击查看专栏目录 本示例是介绍演示如何在vue+mapbox中上传含有shp文件的zip,在地图上显示图形。这里先通过上传解压解析,转换生成geojson文件,然后在地图上渲染图形。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果所用的zip文…

uniapp把文件中的内复制到另一个文件中

使用的是Html 5的plus.io.resolveLocalFileSystemURL方法&#xff0c;文档&#xff1a;HTML5 API Reference var soursePath file:///storage/emulated/0/a/;//用于读取var removePath file:///storage/emulated/0/w/;//用于移除w这个文件夹var targetPath file:///storage/…

nodejs+vue人脸识别考勤管理系统的设计与实现-计算机毕业设计

根据分析&#xff0c;本系统主要有3个角色&#xff1a;管理员、用户、考勤系统。 &#xff08;1&#xff09;管理员&#xff1a;管理员信息的添加、删除、修改和查询&#xff0c;用户信息添加、删除、修改和查询。 &#xff08;2&#xff09;用户&#xff1a;用户的注册和登录&…

AI与Prompt:解锁软件开发团队的魔法咒语,在复杂任务上生成正确率更高的代码

AI与Prompt&#xff1a;解锁软件开发团队的魔法咒语 写在最前面论文&#xff1a;基于ChatGPT的自协作代码生成将团队协作理论应用于代码生成的研究自协作框架原理1、DOL任务分配2、共享黑板协作3、Instance实例化 案例说明简单任务&#xff1a;基本操作&#xff0c;生成的结果1…

c# Json转C#实体

1.Web Api获取 Json数据&#xff1a; { "code": 200, "message": "success", "data": { "Barcode": { "BarcodeNo": "YS5193465232200001", "WorkOrder": "N102304065", "It…