具有多个视图的单页应用程序 (SPA) 需要有一种路由机制,以便在这些不同视图之间导航,而无需刷新整个网页。这可以通过使用诸如React Router之类的路由库来处理。
在本教程中,让我们看看如何使用 React Router v6 库创建路由。本教程将让您了解该库即将推出的一些新功能。
如果你有在 React 应用程序中使用路由的经验,你可能已经知道在过去的几年里,Reach Router已经引起了一些关注。但是,它从版本 6 开始重新合并到 React Router 库中。这确实意味着 v6 版本的包大小比以前的版本小,这是 Reach Router 存在的主要原因之一。
先决条件
要充分利用本教程,请确保您在本地开发环境中安装了以下内容:
入门
首先创建一个新的 React 应用程序。从终端窗口使用以下命令生成项目目录,然后在项目目录中导航并安装所需的依赖项以添加 React Router v6 库:
npx create-react-app react-router-v6-example
cd react-router-v6-example
yarn add history react-router-dom@next
安装依赖项后,在您喜欢的代码编辑器中打开文件,您将看到库的依赖项版本:package.json
react-router-dom
“dependencies": {
// rest of the dependencies installed
"react-router-dom": "6.0.0-beta.0",
},
React Router 库中的不同包
React Router 库包含三个不同的 npm 包,以下每个包都有不同的用途:
react-router
react-router-dom
react-router-native
react-router
包是核心库,用作上面列出的其他两个包的对等依赖项。react-router-dom
是在 React 应用程序中用于路由的包。列表中的最后一个包react-router-native
具有用于开发React Native应用程序的绑定。
现在我们已经涵盖了,让我们构建第一条路线。
使用 React Router v6 创建第一条路由
要使用 React Router 库创建第一个路由,请打开文件并添加以下导入语句:src/App.js
// after other import statements
import { BrowserRouter as Router } from 'react-router-dom';
这是从react-router-dom
库中导入的第一个组件。它用于包装不同的路线。它使用 HTML5 历史 API 来跟踪 React 应用程序中的路由历史。
上面代码片段中的Router
部分是使它更容易编写的别名。建议在 React 应用程序的组件层次结构中的顶级组件中导入和使用它:
function App() {
return <Router>{/* All routes are nested inside it */}</Router>;
}
下一个要导入的组件是react-router-dom
新的Routes
:
import { BrowserRouter as Router, Routes } from 'react-router-dom';
这个新元素是对先前Switch
组件的升级。它包括相对路由和链接、自动路由排名、嵌套路由和布局等功能。
react-router-dom
中的最后一个组件Route
被调用并负责渲染 React 组件的 UI。它有一个名为path
的 prop ,它始终与应用程序的当前 URL 匹配。第二个必需的 prop名为element
被调用,它告诉Route
组件何时遇到当前 URL 以及要呈现哪个 React 组件。这里的element
关键字也是新增的。以前,使用 React Router v5,您将使用名为.component
为了在下面的演示中创建第一个路由,让我们创建一个名为Home
返回一些 JSX 的基本函数组件:
function Home() {
return (
<div style={{ padding: 20 }}>
<h2>Home View</h2>
<p>Lorem ipsum dolor sit amet, consectetur adip.</p>
</div>
);
}
接下来,App
使用以下路由更新功能组件。这里要注意的 v6 库的另一个特性是组件的element
propRoute
现在允许您传递 React 组件,而不仅仅是该 React 组件的名称。这使得沿路线传递道具变得容易:
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
</Routes>
</Router>
);
}
要查看它是否正常工作,请返回终端窗口并使用命令启动开发服务器yarn start
。接下来,在浏览器窗口中访问 URL。http://localhost:3000
这是此步骤之后的输出:
让我们快速创建另一个名为的函数组件,该组件About
仅在浏览器窗口中的 URL 为时呈现:http://localhost:3000/about
function About() {
return (
<div style={{ padding: 20 }}>
<h2>About View</h2>
<p>Lorem ipsum dolor sit amet, consectetur adip.</p>
</div>
);
}
然后,Route
为About
组件添加:
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
现在,返回浏览器窗口并访问 URL :http://localhost:3000/about
添加导航菜单
要导航到 React 应用程序中的特定路线,或演示应用程序中当前存在的两条路线,让我们在Link
组件的帮助下添加一个最小的导航栏 from .react-router-dom
首先从库中导入它:
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
在 HTML 中不同网页之间导航的概念是使用锚标记:
<a href="">Some Link Name</a>
在 React 应用程序中使用这种方法将导致在每次呈现新视图或页面本身时刷新网页。这不是您在使用像 React 这样的库时要寻找的优势。为了避免刷新网页,库提供了该组件。react-router-dom
Link
接下来,在App
函数组件中,创建一个导航栏,如代码片段所示:
<Router>
<nav style={{ margin: 10 }}>
<Link to="/" style={{ padding: 5 }}>
Home
</Link>
<Link to="/about" style={{ padding: 5 }}>
About
</Link>
</nav>
{/* Rest of the code remains same */}
</Router>
转到浏览器窗口以查看正在运行的导航栏:
如何处理嵌套路由
嵌套路由是一个需要理解的重要概念。路由嵌套时,一般假设网页的某个部分保持不变,只有网页的子部分发生变化。
例如,如果您访问一个简单的博客,则始终显示博客的标题,然后在其下方显示博客文章列表。但是,当您单击博客文章时,博客文章列表将替换为该特定博客文章的内容或描述。这是将在本节中执行的示例,以了解如何在最新版本的 React Router 库中处理嵌套路由。
在 React Router v5 中,嵌套路由必须明确定义。React Router v6 并非如此。它从 React Router 库中挑选出最好的元素之一,该库被调用Outlet
来为特定路由渲染任何匹配的子节点。首先,Outlet
从库中导入:react-router-dom
import {
// rest of the elements/components imported remain same
Outlet
} from 'react-router-dom';
为了模仿一个基本的博客,让我们在文件中添加一些模拟数据。代码片段包含一个名为的对象,该对象进一步包含不同的对象作为属性。每个对象由三部分组成:App.js
BlogPosts
- 一个独特的帖子
- 那个帖子的标题
- 该帖子的描述
const BlogPosts = {
'1': {
title: 'First Blog Post',
description: 'Lorem ipsum dolor sit amet, consectetur adip.'
},
'2': {
title: 'Second Blog Post',
description: 'Hello React Router v6'
}
};
这个独特的 slug 将用于 Web 浏览器的 URL 以查看每个帖子的内容。接下来,创建一个名为的函数组件Posts
,其中显示所有博客文章的列表:
function Posts() {
return (
<div style={{ padding: 20 }}>
<h2>Blog</h2>
{/* render any matching child */}
<Outlet />
</div>
);
}
定义另一个称为PostLists
的组件,该组件将在浏览器窗口中的 URL 命中时显示所有帖子的列表。让我们使用 JavaScript方法从 object 返回一个数组。然后映射此数组以显示所有博客文章的标题列表:http://localhost:3000/posts
Object.entries()
BlogPosts
function PostLists() {
return (
<ul>
{Object.entries(BlogPosts).map(([slug, { title }]) => (
<li key={slug}>
<h3>{title}</h3>
</li>
))}
</ul>
);
}
App
像这样修改函数组件中的路由:
<Routes>
{/* Rest of the code remains same */}
<Route path="posts" element={<Posts />}>
<Route path="/" element={<PostLists />} />
</Route>
</Routes>
这表明无论何时触发 URL,都会呈现博客文章列表,因此,组件:http://localhost:3000/posts
PostsLists
如何访问路由的 URL 参数和动态参数
要通过单击呈现的博客文章列表中的文章标题来访问单个文章,您所要做的就是将每个文章的标题包装在Link
组件中的一个组件中PostsLists
。然后,使用每个帖子的 定义每个帖子的路径slug
。/posts/
前缀允许网络浏览器中的路径保持一致:
<ul>
{Object.entries(BlogPosts).map(([slug, { title }]) => (
<li key={slug}>
<Link to={`/posts/${slug}`}>
<h3>{title}</h3>
</Link>
</li>
))}
</ul>
useParams
接下来,导入从库中调用的钩子。这个钩子允许你访问特定路由(或 slug,在这种情况下)可能具有的任何动态参数。每个的动态参数将是每个博客文章的the和 the 。访问它们的需要是在将博客文章的特定 slug 作为浏览器窗口中的 URL 触发时显示每个博客文章的内容:react-router-dom
slug
title
description
import {
// rest of the elements/components imported remain same
useParams
} from 'react-router-dom';
创建一个名为Post
. 该组件将从useParams
钩子中获取帖子的当前 slug。使用 JavaScript 中的方括号符号语法,post
创建一个新变量,该变量具有属性值或博客文章的当前内容。解构这个post
变量的内容,你可以渲染它们:
function Post() {
const { slug } = useParams();
const post = BlogPosts[slug];
const { title, description } = post;
return (
<div style={{ padding: 20 }}>
<h3>{title}</h3>
<p>{description}</p>
</div>
);
}
最后,在函数组件中添加一个动态路由来渲染每个帖子的内容::slug
App
// Rest of the code remains same
<Route path="posts" element={<Posts />}>
<Route path="/" element={<PostLists />} />
<Route path=":slug" element={<Post />} />
</Route>
这是此步骤后的完整输出:
结论
如果你是第一次学习 React Router,希望这篇文章能给你一个很好的介绍。如果您已经熟悉此路由库的任何先前版本,我希望这篇文章能让您大致了解先前版本和最新版本之间的更改。
此GitHub 存储库中提供的源代码。