作者选择Creative Commons接受捐赠,作为Write for DOnations计划的一部分。
介绍
在React 中,路由器帮助创建并在构成 Web 应用程序的不同 URL 之间导航。它们允许您的用户在保留用户状态的同时在应用程序的组件之间移动,并且可以为这些组件提供唯一的 URL 以使其更易于共享。使用路由器,您可以通过简化站点导航来改善应用的用户体验。
React Router是最流行的 React 路由框架之一。该库采用直观的组件设计,可让您为应用程序构建声明性路由系统。这意味着您可以准确地声明哪些组件具有特定路由。使用声明式路由,您可以创建人类可读的直观路由,从而更轻松地管理您的应用程序架构。
在本教程中,您将安装和配置 React Router,构建一组路由,并使用<Link>
组件连接到它们。您还将构建动态路由,从可在组件中访问的 URL 收集数据。最后,您将使用Hook来访问数据和其他路由信息,并创建位于由父路由呈现的组件内部的嵌套路由。
在本教程结束时,您将能够向任何 React 项目添加路由并从路由中读取信息,以便您可以创建响应 URL 数据的灵活组件。
先决条件
-
你需要一个运行Node.js的开发环境;本教程在 Node.js 版本 10.22.0 和 npm 版本 6.14.6 上进行了测试。要在 macOS 或 Ubuntu 18.04 上安装它,请按照如何在 macOS 上安装 Node.js 和创建本地开发环境或如何在 Ubuntu 18.04 上安装 Node.js 的使用 PPA 安装部分中的步骤进行操作。
-
使用Create React App设置的 React 开发环境,删除了非必要的样板。要进行设置,请按照如何管理 React 类组件上的状态教程的步骤 1 — 创建空项目进行操作。本教程将
router-tutorial
用作项目名称。 -
您将在整个教程中使用 React 组件和自定义 Hook。您可以在How To Create Custom Components in React和 Hooks 中了解如何使用 React Components 上的 Hooks 管理状态中的组件。
-
您还需要具备 JavaScript、HTML 和 CSS 的基本知识,您可以在我们的如何使用 HTML 系列构建网站、如何使用 CSS 系列构建网站和如何使用 JavaScript 编码中找到这些知识。
第 1 步 – 安装 React Router
在这一步中,您将把 React Router 安装到您的基础项目中。在这个项目中,您将制作一个关于海洋哺乳动物的小型网站。每个哺乳动物都需要一个单独的组件,您将使用路由器渲染该组件。安装库后,您将为每个哺乳动物创建一系列组件。在此步骤结束时,您将具备根据路线渲染不同哺乳动物的基础。
首先,安装 React Router 包。有两个不同的版本:Web 版本和用于React Native的本机版本。您将安装网络版本。
在您的终端中,使用npm
来安装软件包:
- npm install react-router-dom
将安装该软件包,安装完成后您将收到一条消息,例如此消息。您的信息可能略有不同:
Output...
+ [email protected]
added 11 packages from 6 contributors and audited 1981 packages in 24.897s
114 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
您现在已经安装了该软件包。对于此步骤的其余部分,您将创建一系列组件,每个组件都有唯一的路由。
首先,为三种不同的哺乳动物创建一个目录:海牛、独角鲸和鲸鱼。运行以下命令:
- mkdir src/components/Manatee
- mkdir src/components/Narwhal
- mkdir src/components/Whale
接下来,为每个动物创建一个组件。<h2>
为每个哺乳动物添加一个标签。在一个完整的应用程序中,子组件可以根据您的需要变得复杂。他们甚至可以导入和渲染自己的子组件。在本教程中,您将仅呈现<h2>
标签。
从海牛组件开始。Manatee.js
在文本编辑器中打开:
- nano src/components/Manatee/Manatee.js
然后添加基本组件:
import React from 'react';
export default function Manatee() {
return <h2>Manatee</h2>;
}
保存并关闭文件。
接下来,为独角鲸创建一个组件:
- nano src/components/Narwhal/Narwhal.js
添加相同的基本组件,将 更改<h2>
为Narwhal
:
import React from 'react';
export default function Narwhal() {
return <h2>Narwhal</h2>;
}
保存并关闭文件。
最后,创建一个文件Whale
:
- nano src/components/Whale/Whale.js
添加相同的基本组件,将 更改<h2>
为Whale
:
import React from 'react';
export default function Whale() {
return <h2>Whale</h2>;
}
保存并关闭文件。在下一步中,您将开始连接路由;现在,在您的应用程序中呈现基本组件。
打开App.js
:
- nano src/components/App/App.js
添加<h1>
标签与网站的名称(Marine Mammals
的)里面<div>
有一个className
的wrapper
。这将用作模板。包装器和<h1>
标签将呈现在每个页面上。在完整的应用程序中,您可能会在每个页面上添加导航栏或标题组件。
将以下突出显示的行添加到文件中:
import React from 'react';
import './App.css';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
</div>
);
}
export default App;
接下来,Manatee
在<div>
. 这将用作占位符,直到您添加更多路由:
import React from 'react';
import './App.css';
import Manatee from '../Manatee/Manatee';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<Manatee />
</div>
);
}
export default App;
保存并关闭文件。
现在您已拥有所有组件,请添加一些填充来为应用程序留出一点空间。
打开App.css
:
- nano src/components/App/App.css
然后替换为以下代码,增加了一个内容padding
的20px
给.wrapper
类:
.wrapper {
padding: 20px;
}
保存并关闭文件。当您这样做时,浏览器将刷新以显示您的基本组件:
现在您有了一个基本的根组件,您将使用它来显示其他组件。如果您没有路由器,则可以使用useState
Hook有条件地显示组件。但这不会为您的用户提供良好的体验。每当用户刷新页面时,用户的选择都会消失。此外,他们将无法为应用程序添加书签或共享特定状态。路由器将解决所有这些问题。路由器将保留用户状态,并为用户提供一个清晰的 URL,他们可以保存或发送给其他人。
在这一步中,您安装了 React Router 并创建了基本组件。这些组件将是您将按路线显示的单个页面。在下一步中,您将添加路由并使用该<Link>
组件创建高性能超链接。
第 2 步 – 添加路由
在此步骤中,您将为每个页面创建一个具有单独路由的基本路由器。您将对路由进行排序以确保正确呈现组件,并且您将使用该<Link>
组件向项目添加不会触发页面刷新的超链接。
在此步骤结束时,您将拥有一个带有导航的应用程序,该导航将按路线显示您的组件。
React Router 是一个声明式路由框架。这意味着您将使用标准 React 组件配置路由。这种方法有几个优点。首先,它遵循 React 代码的标准声明性质。您不需要在componentDidMount
方法中或useEffect
Hook 中添加大量代码;您的路线是组件。其次,您可以直观地将路由放置在一个组件内,其他组件作为模板。当您阅读代码时,您会准确地找到动态组件与全局视图(例如导航或页脚)相关的位置。
要开始添加路由,请打开App.js
:
- nano src/components/App/App.js
该 <h1>
标签将用作全局页面标题。由于您希望它出现在每个页面上,因此请在标签后配置路由器。
导入BrowserRouter
,Route
以及Switch
从react-router-dom
。BrowserRouter
将是基本配置。Switch
将包装动态路由,Route
组件将配置特定路由并包装应呈现的组件:
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';
import Manatee from '../Manatee/Manatee';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<Manatee />
</div>
);
}
export default App;
添加BrowserRouter
组件以创建基本路由器。此组件之外的任何内容都将呈现在每个页面上,因此请将其放在您的<h1>
标签之后。此外,如果您有context
要使用的站点范围或其他一些存储(例如Redux ),请将这些组件放在路由器之外。这将使它们可用于任何路线上的所有组件:
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';
import Manatee from '../Manatee/Manatee';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<BrowserRouter>
<Manatee />
</BrowserRouter>
</div>
);
}
export default App;
接下来,将Switch
组件添加到BrowserRouter
. 这个组件将激活正确的路由,很像 JavaScriptswitch
语句。在 内部Switch
,Route
为每个路由添加一个组件。在这种情况下,你会想要以下路线:/manataee
,/narwhal
,和/whale
。该Route
组件将 apath
作为参数并包围子组件。当路由处于活动状态时,子组件将显示。
为路径创建路由/
并渲染Manatee
组件:
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';
import Manatee from '../Manatee/Manatee';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<BrowserRouter>
<Switch>
<Route path="/">
<Manatee />
</Route>
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
保存文件。当您这样做时,浏览器将重新加载,您将找到海牛组件的信息:
如果您尝试不同的路线,例如http://localhost:3000/whale
,您仍然会找到海牛组件。
该Switch
组件将呈现与该模式匹配的第一个路由。任何路由都会匹配/
,因此它会在每个页面上呈现。这也意味着顺序很重要。由于路由器会在找到匹配项后立即退出,因此始终将更具体的路由放在不太具体的路由之前。换句话说,/whale
would go before/
并且/whale/beluga
would go before /whale
。
如果您希望路线仅匹配所写的路线而不是任何子路线,则可以添加该exact
道具。例如,<Route exact path="/manatee">
会匹配/manatee
,但不会匹配/manatee/african
。
将Manatee
组件的路由更新为/manatee
,然后导入其余组件并为每个组件创建一个路由:
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';
import Manatee from '../Manatee/Manatee';
import Narwhal from '../Narwhal/Narwhal';
import Whale from '../Whale/Whale';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<BrowserRouter>
<Switch>
<Route path="/manatee">
<Manatee />
</Route>
<Route path="/narwhal">
<Narwhal />
</Route>
<Route path="/whale">
<Whale />
</Route>
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
保存文件。当您这样做时,浏览器将刷新。如果您访问http://localhost:3000/
,则只会<h1>
呈现标签,因为没有路由匹配任何Route
组件:
如果您访问http://localhost:3000/whale
,您将找到该Whale
组件:
现在您有一些组件,为用户创建导航以在页面之间移动。
使用<nav>
元素表示您正在创建页面的导航部分。然后为每个哺乳动物添加一个<ul>
带有列表项 ( <li>
) 和超链接 ( <a>
)的无序列表 ( ) :
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';
import Manatee from '../Manatee/Manatee';
import Narwhal from '../Narwhal/Narwhal';
import Whale from '../Whale/Whale';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<nav>
<ul>
<li><a href="/manatee">Manatee</a></li>
<li><a href="/narwhal">Narwhal</a></li>
<li><a href="/whale">Whale</a></li>
</ul>
</nav>
<BrowserRouter>
...
</BrowserRouter>
</div>
);
}
export default App;
保存文件。当你这样做时,浏览器会刷新,但会出现问题。由于您使用的是本地浏览器链接——<a>
标签——您将在任何时候单击链接时获得默认浏览器行为。这意味着每当您单击链接时,都会触发整页刷新。
请注意,当您单击链接时,网络将重新加载所有 JavaScript 文件。这对您的用户来说是一个巨大的性能成本。
此时,您可以在每个链接上添加一个click
事件处理程序并阻止默认操作。那将是很多工作。相反,React Router 有一个名为的特殊组件Link
,它将为您处理工作。它将创建一个链接标签,但在推送新位置时阻止默认浏览器行为。
在 中App.js
,Link
从react-router-dom
. 然后<a>
用一个Link
. 您还需要将href
属性更改为to
道具。
最后,将<nav>
组件移动到BrowserRouter
. 这确保了该Link
组件由react-router
以下控制:
import React from 'react';
import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
import './App.css';
import Manatee from '../Manatee/Manatee';
import Narwhal from '../Narwhal/Narwhal';
import Whale from '../Whale/Whale';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<BrowserRouter>
<nav>
<ul>
<li><Link to="/manatee">Manatee</Link></li>
<li><Link to="/narwhal">Narwhal</Link></li>
<li><Link to="/whale">Whale</Link></li>
</ul>
</nav>
<Switch>
<Route path="/manatee">
<Manatee />
</Route>
<Route path="/narwhal">
<Narwhal />
</Route>
<Route path="/whale">
<Whale />
</Route>
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
保存文件。当您这样做时,浏览器将刷新。单击链接时,页面不会刷新,浏览器也不会重新加载 JavaScript 代码:
在这一步中,您将 React Router 添加到您当前的项目中。您为每个组件创建了一个路由,并添加了使用该Link
组件在路由之间切换而无需刷新页面的导航。
在下一步中,您将添加更复杂的路由,这些路由使用 URL 参数呈现不同的组件。
第 3 步 – 使用 Hook 访问路由数据
在此步骤中,您将使用 URL 查询和参数来创建动态路由。您将学习如何使用useLocation
Hook从搜索参数中提取信息,以及如何使用useParams
Hook从动态 URL 中读取信息。
在这一步结束时,您将知道如何访问组件内部的路由信息以及如何使用该信息来动态加载组件。
假设您想为您的海洋哺乳动物应用程序添加另一个级别。鲸鱼的种类很多,您可以显示每一种鲸鱼的信息。您有两种实现方式的选择:您可以使用当前路线并添加具有搜索参数的特定鲸鱼类型,例如?type=beluga
. 您还可以创建一个新路由,在基本 URL 后包含特定名称,例如/whale/beluga
. 本教程将从搜索参数开始,因为它们很灵活并且可以处理多个不同的查询。
首先,为不同的鲸鱼种类制作新的组件。
Beluga.js
在文本编辑器中打开一个新文件:
- nano src/components/Whale/Beluga.js
添加<h3>
名称为 的标签Beluga
:
import React from 'react';
export default function Beluga() {
return(
<h3>Beluga</h3>
);
}
对蓝鲸做同样的事情。Blue.js
在文本编辑器中打开一个新文件:
- nano src/components/Whale/Blue.js
添加<h3>
名称为 的标签Blue
:
import React from 'react';
export default function Blue() {
return(
<h3>Blue</h3>
);
}
保存并关闭文件。
使用搜索参数传递附加信息
接下来,您要将鲸鱼信息作为搜索参数传递。这将使您无需创建新 URL 即可传递信息。
打开App.js
以便您可以添加新链接:
- nano src/components/App/App.js
添加两个新链接,一个 to/whale?type=beluga
一个 for /whale?type=blue
:
import React from 'react';
import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
import './App.css';
import Manatee from '../Manatee/Manatee';
import Narwhal from '../Narwhal/Narwhal';
import Whale from '../Whale/Whale';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<BrowserRouter>
<nav>
<ul>
<li><Link to="/manatee">Manatee</Link></li>
<li><Link to="/narwhal">Narwhal</Link></li>
<li><Link to="/whale">Whale</Link></li>
<li><Link to="/whale?type=beluga">Beluga Whale</Link></li>
<li><Link to="/whale?type=blue">Blue Whale</Link></li>
</ul>
</nav>
<Switch>
...
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
保存并关闭文件。
如果您单击链接,您仍会看到常规的鲸鱼页面。这表明标准路由仍然正常工作:
由于您正确呈现Whale
组件,因此您需要更新组件以从 URL 中提取搜索查询并使用它来呈现正确的子组件。
打开Whale.js
:
- nano src/components/Whale/Whale.js
首先,导入Beluga
和Blue
组件。接下来,导入一个名为useLocation
from的 Hook react-router-dom
:
import React from 'react';
import { useLocation } from 'react-router-dom';
import Beluga from './Beluga';
import Blue from './Blue';
export default function Whale() {
return <h2>Whale</h2>;
}
该useLocation
钩拉从你的页面的位置信息。这不是 React Router 独有的。该location
对象是所有浏览器上的标准对象。如果您打开浏览器控制台并键入window.location
,您将获得一个包含有关您的 URL 的信息的对象。
请注意,位置信息包括search
,但也包括其他信息,例如pathname
和完整href
。该useLocation
钩子将提供这些信息给你。在 内部Whale.js
,调用useLocation
Hook。解构结果以拉出该search
字段。这将是一个参数字符串,例如?type=beluga
:
import React from 'react';
import { useLocation } from 'react-router-dom';
import Beluga from './Beluga';
import Blue from './Blue';
export default function Whale() {
const { search } = useLocation();
return <h2>Whale</h2>;
}
有许多库,例如query-string
,可以为您解析搜索并将其转换为更易于阅读和更新的对象。在本例中,您可以使用正则表达式来提取有关鲸鱼的信息type
。
使用.match
搜索字符串上的方法拉出type
: search.match(/type=(.*)/)
。正则表达式内的括号将匹配捕获到结果数组中。数组中的第一项是完整匹配项:type=beluga
。第二项是括号中的信息:beluga
。
使用.match
方法中的数据来渲染正确的子组件:
import React from 'react';
import { useLocation } from 'react-router-dom';
import Beluga from './Beluga';
import Blue from './Blue';
export default function Whale() {
const { search } = useLocation();
const match = search.match(/type=(.*)/);
const type = match?.[1];
return (
<>
<h2>Whale</h2>
{type === 'beluga' && <Beluga />}
{type === 'blue' && <Blue />}
</>
);
}
该符号?.
称为可选链接。如果该值存在,则返回该值。否则,它将返回undefined
。这将在搜索参数为空的情况下保护您的组件。
保存文件。当您这样做时,浏览器将刷新并呈现不同的鲸鱼:
访问 URL 参数
搜索参数有效,但在这种情况下它们不是最佳解决方案。通常,您会使用搜索参数来优化页面:切换信息或加载特定数据。在这种情况下,您不是在优化页面;您正在创建一个新的静态页面。幸运的是,React Router 提供了一种创建动态 URL 的方法,这些 URL 保留称为 URL 参数的可变数据。
打开App.js
:
- nano src/components/App/App.js
您无需将鲸鱼信息作为搜索传递,而是将其直接添加到 URL 本身。这意味着您会将搜索移动到 URL 中,而不是将其添加到?
. 例如,查询/whale?type=blue
现在将是/whale/blue
:
import React from 'react';
import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
import './App.css';
import Manatee from '../Manatee/Manatee';
import Narwhal from '../Narwhal/Narwhal';
import Whale from '../Whale/Whale';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<BrowserRouter>
<nav>
<ul>
<li><Link to="/manatee">Manatee</Link></li>
<li><Link to="/narwhal">Narwhal</Link></li>
<li><Link to="/whale">Whale</Link></li>
<li><Link to="/whale/beluga">Beluga Whale</Link></li>
<li><Link to="/whale/blue">Blue Whale</Link></li>
</ul>
</nav>
<Switch>
<Route path="/manatee">
<Manatee />
</Route>
<Route path="/narwhal">
<Narwhal />
</Route>
<Route path="/whale">
<Whale />
</Route>
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
现在您需要创建一个可以同时捕获/whale/beluga
和的新路由/whale/blue
。您可以手动添加它们,但这在您不知道所有可能性的情况下不起作用,例如当您有用户列表或其他动态数据时。
不是为每个路径都创建一个路由,而是将一个 URL 参数添加到当前路径。URL 参数是一个以冒号开头的关键字。React Router 将使用该参数作为通配符,并将匹配包含该模式的任何路由。
在这种情况下,创建一个关键字:type
。全path
将/whale/:type
。这将匹配以 开头的任何路由,/whale
并将变量信息保存在名为 的参数变量中type
。此路由将不匹配/whale
,因为它不包含附加参数。
您可以/whale
在新路由之后添加为路由,也可以/whale/:type
使用exact
关键字将其添加在路由之前。
添加一个新的路由/whale/:type
并exact
为当前路由添加一个属性:
import React from 'react';
import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
import './App.css';
import Manatee from '../Manatee/Manatee';
import Narwhal from '../Narwhal/Narwhal';
import Whale from '../Whale/Whale';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<BrowserRouter>
<nav>
<ul>
<li><Link to="/manatee">Manatee</Link></li>
<li><Link to="/narwhal">Narwhal</Link></li>
<li><Link to="/whale">Whale</Link></li>
<li><Link to="/whale/beluga">Beluga Whale</Link></li>
<li><Link to="/whale/blue">Blue Whale</Link></li>
</ul>
</nav>
<Switch>
<Route path="/manatee">
<Manatee />
</Route>
<Route path="/narwhal">
<Narwhal />
</Route>
<Route exact path="/whale">
<Whale />
</Route>
<Route path="/whale/:type">
<Whale />
</Route>
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
保存并关闭文件。现在您正在传递新信息,您需要访问它并使用该信息来呈现动态组件。
打开Whale.js
:
- nano src/components/Whale/Whale.js
导入useParams
钩子。这将连接到您的路由器并将所有 URL 参数提取到一个对象中。解构物体以拉出场type
。去掉解析的代码search
,使用参数有条件地渲染子组件:
import React from 'react';
import { useParams } from 'react-router-dom';
import Beluga from './Beluga';
import Blue from './Blue';
export default function Whale() {
const { type } = useParams();
return (
<>
<h2>Whale</h2>
{type === 'beluga' && <Beluga />}
{type === 'blue' && <Blue />}
</>
);
}
保存并关闭文件。当您这样做时,浏览器将刷新并且您将能够使用新的 URL,例如http://localhost:3000/whale/beluga
:
URL 参数是传递条件数据的一种明确方式。它们不像搜索参数那样灵活,可以组合或重新排序,但它们更清晰,更容易被搜索引擎索引。
在此步骤中,您使用搜索参数和 URL 参数传递了可变数据。您还使用useLocation
和useParams
钩子提取信息并呈现条件组件。
但是有一个问题:路线列表越来越长,并且您开始接近与/whale
和/whale/:type
路线的重复项。React Router 允许您直接在组件中拆分子路由,这意味着您不需要在单个组件中拥有整个列表。在下一步中,您将直接在子组件内部渲染路由。
第 4 步 – 嵌套路由
路由可以增长并变得更加复杂。React Router 使用嵌套路由在子组件内部呈现更具体的路由信息。在这一步中,您将使用嵌套路由并在不同的组件中添加路由。在此步骤结束时,您将有不同的选项来呈现您的信息。
在最后一步中,您在App.js
. 这有一些优点:它将所有路由保存在一个地方,本质上为您的应用程序创建了一个站点地图。但是它很容易增长并且难以阅读和维护。嵌套路由将您的路由信息直接分组在将呈现其他组件的组件中,使您能够在整个应用程序中创建迷你模板。
打开App.js
:
- nano src/components/App/App.js
移除/whale/:type
路线并移除exact
道具,这样你就只有一条鲸鱼路线:
import React from 'react';
import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
import './App.css';
import Manatee from '../Manatee/Manatee';
import Narwhal from '../Narwhal/Narwhal';
import Whale from '../Whale/Whale';
function App() {
return (
<div className="wrapper">
<h1>Marine Mammals</h1>
<BrowserRouter>
<nav>
<ul>
<li><Link to="/manatee">Manatee</Link></li>
<li><Link to="/narwhal">Narwhal</Link></li>
<li><Link to="/whale">Whale</Link></li>
<li><Link to="/whale/beluga">Beluga Whale</Link></li>
<li><Link to="/whale/blue">Blue Whale</Link></li>
</ul>
</nav>
<Switch>
<Route path="/manatee">
<Manatee />
</Route>
<Route path="/narwhal">
<Narwhal />
</Route>
<Route path="/whale">
<Whale />
</Route>
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
保存并关闭文件。
接下来,打开Whale.js
。您将在此处添加嵌套路由。
- nano src/components/Whale/Whale.js
你需要做两件事。首先,使用useRouteMatch
Hook获取当前路径。接下来,渲染新的<Switch>
和<Route>
组件以显示正确的组件。
进口useRouteMatch
。这将返回一个包含path
和 的对象url
。解构对象以获取path
. 您将使用它作为新路线的基础:
import React from 'react';
import { useRouteMatch } from 'react-router-dom';
import Beluga from './Beluga';
import Blue from './Blue';
export default function Whale() {
const { path } = useRouteMatch();
return (
<>
<h2>Whale</h2>
{type === 'beluga' && <Beluga />}
{type === 'blue' && <Blue />}
</>
);
}
接下来,导入Switch
,Route
以便您可以添加新路由。您的新路线将与您在 中创建的路线相同App.js
,但您无需将它们用 包裹起来BrowserRouter
。添加新路由,但在路由前加上path
. 新组件将准确呈现您放置它们的位置,因此在 之后添加新路由<h2>
:
import React from 'react';
import { Switch, Route, useRouteMatch } from 'react-router-dom';
import Beluga from './Beluga';
import Blue from './Blue';
export default function Whale() {
const { path } = useRouteMatch();
return (
<>
<h2>Whale</h2>
<Switch>
<Route path={`${path}/beluga`}>
<Beluga />
</Route>
<Route path={`${path}/blue`}>
<Blue />
</Route>
</Switch>
</>
);
}
保存文件。当您这样做时,浏览器将刷新并且您将能够访问子路由。
这是一些额外的代码,但它使子路由与父路由保持一致。并非所有项目都使用嵌套路由:有些项目更喜欢有一个明确的列表。这是团队偏好和一致性的问题。选择最适合您的项目的选项,您可以随时进行重构。
在此步骤中,您向项目添加了嵌套路由。您使用useRouteMatch
Hook拉出当前路径并在组件中添加新路由以在基本组件内呈现新组件。
结论
React Router 是任何 React 项目的重要组成部分。当您构建单页应用程序时,您将使用路由将您的应用程序分成用户可以轻松且一致地访问的可用部分。
当您开始将组件分成路由时,您将能够利用代码拆分、通过查询参数保留状态和其他工具来改善用户体验。
如果您想阅读更多 React 教程,请查看我们的React 主题页面,或返回“如何在 React.js 中编码”系列页面。