作者选择了 Creative Commons以作为 Write for Donations计划的一部分获得捐赠。
介绍
在 React, routers 帮助创建和导航构成您的 Web 应用程序的不同 URL. 它们允许您的用户在应用程序的 组件之间移动,同时保持用户的 状态,并可以为这些组件提供独特的 URL,使其更可共享。
React Router是React最受欢迎的路由框架之一. 该库采用直观的组件设计,允许您为您的应用程序构建一个声明路由系统. 这意味着您可以准确地声明您的组件中哪个具有特定路由。
在本教程中,您将安装和配置React Router,构建一组路由器,并使用<Link>
组件连接到它们。您还将构建动态路由器,从您可以在组件中访问的URL中收集数据。最后,您将使用Hooks访问数据和其他路由器信息,并创建嵌入式路由器,这些路由器是由家长路由器渲染的组件。
到本教程结束时,您将能够向任何 React 项目添加路线,并从路线中阅读信息,以便您可以创建响应 URL 数据的灵活组件。
前提条件
- 联合国 您需要一个运行 [Node.js] (https://nodejs.org/en/about/) 的开发环境; 此教程在 Node.js 版本 10.22.0 和 npm 版本 6.14.6. 上进行了测试 。 要在 macOS 或 Ubuntu 18.04 上安装,请遵循 [如何在 macOS (https://andsky.com/tech/tutorials/how-to-install-node-js-and-create-a-local-development-environment-on-macos 上安装节点并创建本地开发环境] (https://andsky.com/tech/tutorials/how-to-install-node-js-on-ubuntu-18-04) 或 ** 使用 [如何在 Ubuntu 18.04 (https://andsky.com/tech/tutorials/how-to-install-node-js-on-ubuntu-18-04 上安装节点.js] 的 PPA** 部分。
*A React开发环境由Create React App所设置,非必需锅炉板被去除. 要设置此功能, 请遵循 [步骤1—— 创建一个空项目, 如何管理响应类组件的状态教程] (https://andsky.com/tech/tutorials/how-to-manage-state-on-react-class-components#step-1-%E2%80%94-creating-an-empty-project) 。 此教程将使用
router- tutorial
作为项目名称。 % 您将在整个教程中使用 React 组件和自定义 Hooks 。 您可以在 [如何在反应中创建自定义组件 (https://andsky.com/tech/tutorials/how-to-create-custom-components-in-react) 和 Hooks 在 [如何在反应组件上使用钩子管理状态 (https://andsky.com/tech/tutorials/how-to-manage-state-with-hooks-on-react-components ) 中学习组件 - 您还需要JavaScript, HTML, CSS的基本知识, 您可以在 [How To Build a website With HTML series] (https://www.digitalocean.com/community/tutorial_series/how-to-build-a-website-with-html), [How To Build a website With CSS series] (https://www.digitalocean.com/community/tutorial_series/how-to-build-a-website-with-css) 和 [How To Code in JavaScript] (https://www.digitalocean.com/community/tutorial_series/how-to-code-in-javascript)中找到这些知识. (韩语)_
步骤 1 – 安装 React 路由器
在此步骤中,您将安装 React Router 到您的基础项目中。在本项目中,您将创建一个关于海洋哺乳动物的小网站。每个哺乳动物将需要一个单独的组件,您将与路由器进行渲染。安装图书馆后,您将为每个哺乳动物创建一系列组件。到此步骤结束时,您将根据路线创建一个不同的哺乳动物渲染的基础。
要开始,安装 React Router 包. 有两种不同的版本:一个网页版本和一个原生版本用于使用 React Native。
在您的终端中,使用 npm
来安装该包:
1npm install react-router-dom
该包将安装,您将在安装完成后收到这样的消息. 您的消息可能略有不同:
1[secondary_label Output]
2...
3+ [email protected]
4added 11 packages from 6 contributors and audited 1981 packages in 24.897s
5
6114 packages are looking for funding
7 run `npm fund` for details
8
9found 0 vulnerabilities
此步骤的剩余时间,你将创建一系列的组件,每个组件将有一个独特的路径。
要开始,为三个不同的哺乳动物创建一个目录:马纳特,鲸和鲸鱼。
1mkdir src/components/Manatee
2mkdir src/components/Narwhal
3mkdir src/components/Whale
接下来,为每个动物创建一个组件。为每个哺乳动物添加一个<h2>
标签。在一个完整的应用程序中,儿童组件可以像你想要的那样复杂。他们甚至可以导入和渲染自己的儿童组件。
从 manatee 组件开始,在文本编辑器中打开Manatee.js
:
1nano src/components/Manatee/Manatee.js
然后添加基本成分:
1[label router-tutorial/src/components/Manatee/Manatee.js]
2import React from 'react';
3
4export default function Manatee() {
5 return <h2>Manatee</h2>;
6}
保存并关闭文件。
接下来,为Narwhal创建一个组件:
1nano src/components/Narwhal/Narwhal.js
添加相同的基本组件,将<h2>
更改为Narwhal
:
1[label router-tutorial/src/components/Narwhal/Narwhal.js]
2import React from 'react';
3
4export default function Narwhal() {
5 return <h2>Narwhal</h2>;
6}
保存并关闭文件。
最后,为鲸鱼
创建一个文件:
1nano src/components/Whale/Whale.js
添加相同的基本组件,将<h2>
更改为鲸鱼
:
1[label router-tutorial/src/components/Whale/Whale.js]
2import React from 'react';
3
4export default function Whale() {
5 return <h2>Whale</h2>;
6}
在下一步,您将开始连接路径;目前,将应用程序中的基本组件渲染。
打开App.js
:
1nano src/components/App/App.js
添加一个<h1>
标签,包含网站的名称(海洋哺乳动物
)在一个<div>
内,包含一个className
的wrapper
。这将作为一个模板。包装和<h1>
标签将在每个页面上呈现。在完整的应用程序中,您可能会在每个页面上添加您想要的导航栏或标题组件。
添加以下突出的行到文件中:
1[label router-tutorial/src/components/App/App.js]
2import React from 'react';
3import './App.css';
4function App() {
5 return (
6 <div className="wrapper">
7 <h1>Marine Mammals</h1>
8 </div>
9 );
10}
11
12export default App;
接下来,导入Manatee
并在div>
内渲染。
1[label router-tutorial/src/components/App/App.js]
2
3import React from 'react';
4import './App.css';
5
6import Manatee from '../Manatee/Manatee';
7
8function App() {
9 return (
10 <div className="wrapper">
11 <h1>Marine Mammals</h1>
12 <Manatee />
13 </div>
14 );
15}
16
17export default App;
保存并关闭文件。
现在你已经有所有组件,添加一些垫子来给应用程序一点空间。
打开App.css
:
1nano src/components/App/App.css
然后用以下代码代替内容,将20px
的padding
添加到.wrapper
类:
1[label router-tutorial/src/components/App/App.css]
2.wrapper {
3 padding: 20px;
4}
保存和关闭文件. 当您这样做时,浏览器将更新以显示您的基本组件:
现在你有一个基本的根组件,你会用来显示其他组件. 如果你没有路由器,你可以使用 useState
Hook条件显示组件。但这不会为你的用户提供一个很好的体验。 每当用户更新页面时,用户的选择都会消失。 此外,他们将无法标记或共享应用程序的特定状态。 路由器将解决所有这些问题。 路由器将保留用户的状态,并给用户一个清晰的URL,他们可以保存或发送给其他人。
在此步骤中,您安装了 React Router 并创建了基本组件. 组件将是单个页面,您将按路线显示。 在下一步中,您将添加路线并使用<Link>
组件创建高效的超链接。
步骤2 - 添加路线
在此步骤中,您将创建一个基路由器,每个页面都有个别路由器,您将订购路由器,以确保组件的渲染正确,您将使用<链接>
组件添加超链接到您的项目,不会触发页面更新。
在此步骤结束时,您将有一个具有导航的应用程序,该应用程序将根据路线显示您的组件。
React Router 是一个声明路由框架,这意味着您将使用标准 React 组件配置路径。 这种方法有几个优点。 首先,它遵循 React 代码的标准声明性质。 您不需要在 componentDidMount
方法中或在 useEffect
Hook 中添加大量代码; 您的路径是组件。 其次,您可以直观地将路由置于组件内,其他组件作为模板。 当您阅读代码时,您将确切地发现动态组件将与全球视图(如导航或脚踏板)相关。
要开始添加路线,请打开App.js
:
1nano src/components/App/App.js
<h1>
标签将作为一个全球页面标题,因为你希望它出现在每个页面上,配置路由器后标签。
导入BrowserRouter
,Route
和Switch
从react-router-dom
。BrowserRouter
将是基本配置。Switch
将包装动态路径,而Route
组件将配置特定路径并包装该组件,该组件应:
1[label router-tutorial/src/components/App/App.js]
2import React from 'react';
3import { BrowserRouter, Route, Switch } from 'react-router-dom';
4import './App.css';
5
6import Manatee from '../Manatee/Manatee';
7
8function App() {
9 return (
10 <div className="wrapper">
11 <h1>Marine Mammals</h1>
12 <Manatee />
13 </div>
14 );
15}
16
17export default App;
添加BrowserRouter
组件来创建一个基本路由器. 该组件之外的任何东西都会在每个页面上进行渲染,所以在您的<h1>
标签后放置它。 此外,如果您有您想要使用的整个网站的context
(https://andsky.com/tech/tutorials/how-to-share-state-across-react-components-with-context)或其他商店,如Redux
(https://andsky.com/tech/tutorials/how-to-manage-state-in-react-with-redux),则将这些组件放置在路由器外面。
1[label router-tutorial/src/components/App/App.js]
2import React from 'react';
3import { BrowserRouter, Route, Switch } from 'react-router-dom';
4import './App.css';
5
6import Manatee from '../Manatee/Manatee';
7
8function App() {
9 return (
10 <div className="wrapper">
11 <h1>Marine Mammals</h1>
12 <BrowserRouter>
13 <Manatee />
14 </BrowserRouter>
15 </div>
16 );
17}
18
19export default App;
接下来,在BrowserRouter
中添加Switch
组件。这个组件会激活正确的路线,就像JavaScript(switch
声明)一样(https://andsky.com/tech/tutorials/how-to-use-the-switch-statement-in-javascript)。在Switch
内部,为每个路线添加一个Route
组件。在这种情况下,您将需要以下路线: /manataee
, /narwhal
和 /whale
。
为路径 /
创建路径,并返回 Manatee
组件:
1[label router-tutorial/src/components/App/App.js]
2import React from 'react';
3import { BrowserRouter, Route, Switch } from 'react-router-dom';
4import './App.css';
5
6import Manatee from '../Manatee/Manatee';
7
8function App() {
9 return (
10 <div className="wrapper">
11 <h1>Marine Mammals</h1>
12 <BrowserRouter>
13 <Switch>
14 <Route path="/">
15 <Manatee />
16 </Route>
17 </Switch>
18 </BrowserRouter>
19 </div>
20 );
21}
22
23export default App;
当你这样做时,浏览器将重新加载,你会发现 manatee 组件的信息:
如果你尝试不同的路线,如 http://localhost:3000/whale
,你仍然会找到 manatee 组件。
Switch
组件将显示与该模式匹配的第一个路线. 任何路线将匹配 /
,所以它将在每个页面上进行。 这也意味着这个命令很重要。 由于路由器一旦找到一个匹配,就会退出,所以总是在不太具体的路线之前设置一个更具体的路线。
如果您希望路线仅与所写的路线匹配,而不是任何儿童路线,则可以添加准确
标签,例如,<路线准确路径="/manatee">
将匹配/manatee
,但不会匹配/manatee/african
。
更新Manatee
组件的路线到/manatee
,然后导入剩余的组件并为每个组件创建路线:
1[label router-tutorial/src/components/App/App.js]
2import React from 'react';
3import { BrowserRouter, Route, Switch } from 'react-router-dom';
4import './App.css';
5
6import Manatee from '../Manatee/Manatee';
7import Narwhal from '../Narwhal/Narwhal';
8import Whale from '../Whale/Whale';
9
10function App() {
11 return (
12 <div className="wrapper">
13 <h1>Marine Mammals</h1>
14 <BrowserRouter>
15 <Switch>
16 <Route path="/manatee">
17 <Manatee />
18 </Route>
19 <Route path="/narwhal">
20 <Narwhal />
21 </Route>
22 <Route path="/whale">
23 <Whale />
24 </Route>
25 </Switch>
26 </BrowserRouter>
27 </div>
28 );
29}
30
31export default App;
如果您访问 http://localhost:3000/
,只会显示 <h1>
标签,因为没有路线匹配任何的 Route
组件:
如果你访问 http://localhost:3000/whale
,你会发现鲸鱼
组件:
现在你有一些组件,创建导航,让用户在页面之间移动。
使用<nav>
元素表示您正在创建页面的导航部分,然后为每个哺乳动物添加一个未分类的列表(<ul>
)和一个列表项(<li>
)和一个超链接(<a>
):
1[label router-tutorial/src/components/App/App.js]
2import React from 'react';
3import { BrowserRouter, Route, Switch } from 'react-router-dom';
4import './App.css';
5
6import Manatee from '../Manatee/Manatee';
7import Narwhal from '../Narwhal/Narwhal';
8import Whale from '../Whale/Whale';
9
10function App() {
11 return (
12 <div className="wrapper">
13 <h1>Marine Mammals</h1>
14 <nav>
15 <ul>
16 <li><a href="/manatee">Manatee</a></li>
17 <li><a href="/narwhal">Narwhal</a></li>
18 <li><a href="/whale">Whale</a></li>
19 </ul>
20 </nav>
21 <BrowserRouter>
22 ...
23 </BrowserRouter>
24 </div>
25 );
26}
27
28export default App;
当您这样做时,浏览器将更新,但会出现问题. 由于您正在使用本地浏览器链接 - <a>
标签 - 您每次点击链接时都会收到默认浏览器行为。
请注意,当您点击链接时,网络将重新加载所有JavaScript文件,这对您的用户来说是一个巨大的性能成本。
在这一点上,你可以在每个链接上添加一个点击
(LINK0
)并防止默认操作,这将是大量的工作。相反,React Router有一个名为Link
的特殊组件,将为你处理工作。
在App.js
中,从react-router-dom
导入Link
,然后将每个<a>
代替为Link
。
最后,将<nav>
组件移动到BrowserRouter
内部,以确保Link
组件由react-router
控制:
1[label router-tutorial/src/components/App/App.js]
2
3import React from 'react';
4import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
5import './App.css';
6
7import Manatee from '../Manatee/Manatee';
8import Narwhal from '../Narwhal/Narwhal';
9import Whale from '../Whale/Whale';
10
11function App() {
12 return (
13 <div className="wrapper">
14 <h1>Marine Mammals</h1>
15 <BrowserRouter>
16 <nav>
17 <ul>
18 <li><Link to="/manatee">Manatee</Link></li>
19 <li><Link to="/narwhal">Narwhal</Link></li>
20 <li><Link to="/whale">Whale</Link></li>
21 </ul>
22 </nav>
23 <Switch>
24 <Route path="/manatee">
25 <Manatee />
26 </Route>
27 <Route path="/narwhal">
28 <Narwhal />
29 </Route>
30 <Route path="/whale">
31 <Whale />
32 </Route>
33 </Switch>
34 </BrowserRouter>
35 </div>
36 );
37}
38
39export default App;
保存文件. 当您这样做时,浏览器会更新. 当您点击链接时,页面不会更新,浏览器不会重新加载JavaScript代码:
在此步骤中,您将 React Router 添加到当前项目中,为每个组件创建了路线,并使用链接
组件添加了导航,以便在没有更新页面的情况下切换路线。
在下一步中,您将添加更复杂的路径,这些路径将使用 URL 参数渲染不同的组件。
步骤 3 – 使用胡克访问路线数据
在此步骤中,您将使用 URL 查询和参数创建动态路径,您将学习如何使用 useLocation
Hook 从搜索参数中提取信息,以及如何使用 useParams
Hook 从动态 URL 读取信息。
在此步骤结束时,您将知道如何访问组件内部的路由信息,以及如何使用该信息动态加载组件。
假设你想为你的海洋哺乳动物应用程序添加另一个级别。有许多类型的鲸鱼,你可以显示有关每个类型的信息。你有两种选择,如何做到这一点:你可以使用当前的路线,并添加特定类型的鲸鱼与搜索参数,如?type=beluga。
首先,为不同的鲸鱼物种制作新的组件。
在文本编辑器中打开新文件 Beluga.js
:
1nano src/components/Whale/Beluga.js
添加一个名为Beluga
的<h3>
标签:
1[label router-tutorial/src/components/Whale/Beluga.js]
2import React from 'react';
3
4export default function Beluga() {
5 return(
6 <h3>Beluga</h3>
7 );
8}
对蓝鲸做同样的事情. 在文本编辑器中打开一个新的文件Blue.js
:
1nano src/components/Whale/Blue.js
添加一个名为Blue
的<h3>
标签:
1[label router-tutorial/src/components/Whale/Blue.js]
2import React from 'react';
3
4export default function Blue() {
5 return(
6 <h3>Blue</h3>
7 );
8}
保存并关闭文件。
通过搜索参数传递额外信息
接下来,您将将鲸鱼信息传递为 搜索参数。
打开App.js
,以便添加新的链接:
1nano src/components/App/App.js
添加两个新的链接,一个为 /whale?type=beluga
和一个为 /whale?type=blue
:
1[label router-tutorial/src/components/App/App.js]
2import React from 'react';
3import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
4import './App.css';
5
6import Manatee from '../Manatee/Manatee';
7import Narwhal from '../Narwhal/Narwhal';
8import Whale from '../Whale/Whale';
9
10function App() {
11 return (
12 <div className="wrapper">
13 <h1>Marine Mammals</h1>
14 <BrowserRouter>
15 <nav>
16 <ul>
17 <li><Link to="/manatee">Manatee</Link></li>
18 <li><Link to="/narwhal">Narwhal</Link></li>
19 <li><Link to="/whale">Whale</Link></li>
20 <li><Link to="/whale?type=beluga">Beluga Whale</Link></li>
21 <li><Link to="/whale?type=blue">Blue Whale</Link></li>
22 </ul>
23 </nav>
24 <Switch>
25 ...
26 </Switch>
27 </BrowserRouter>
28 </div>
29 );
30}
31
32export default App;
保存并关闭文件。
如果你点击链接,你仍然会看到正常的鲸鱼页面. 这表明标准路线仍然正常工作:
由于您正在正确渲染鲸鱼
组件,您需要更新该组件以将搜索查询从URL中拉出来,并使用它来渲染正确的孩子组件。
打开Whale.js
:
1nano src/components/Whale/Whale.js
首先,导入Beluga
和Blue
组件,然后从react-router-dom
导入名为useLocation
的:
1[label router-tutorial/src/components/Whale/Whale.js]
2import React from 'react';
3import { useLocation } from 'react-router-dom';
4import Beluga from './Beluga';
5import Blue from './Blue';
6
7export default function Whale() {
8 return <h2>Whale</h2>;
9}
该useLocation
链接从您的页面中提取位置信息,这不是 React Router 独一无二的。该位置
对象是 所有浏览器上的标准对象。 如果您打开浏览器控制台并键入window.location
,您将收到有关您的 URL 的信息的对象。
请注意,位置信息包括搜索
,但也包括其他信息,如路径名称
和完整的href
。useLocation
链接将为您提供此信息。在Whale.js
内部,拨打useLocation
链接。
1[label router-tutorial/src/components/Whale/Whale.js]
2import React from 'react';
3import { useLocation } from 'react-router-dom';
4import Beluga from './Beluga';
5import Blue from './Blue';
6
7export default function Whale() {
8 const { search } = useLocation();
9 return <h2>Whale</h2>;
10}
有许多库,例如 query-string
,可以为您解析搜索,并将其转换为更容易阅读和更新的 object。
在搜索字符串中使用 .match
方法来抽出 type
: search.match(/type=(.*)/)
. 正规表达式中的插座将捕捉匹配的结果 array。 数组中的第一个项目是完整的匹配: type=beluga
. 第二个项目是插座中的信息: beluga
。
使用「.match」方法的数据来渲染正确的孩子组件:
1[label router-tutorial/src/components/Whale/Whale.js]
2
3import React from 'react';
4import { useLocation } from 'react-router-dom';
5import Beluga from './Beluga';
6import Blue from './Blue';
7
8export default function Whale() {
9 const { search } = useLocation();
10 const match = search.match(/type=(.*)/);
11 const type = match?.[1];
12
13 return (
14 <>
15 <h2>Whale</h2>
16 {type === 'beluga' && <Beluga />}
17 {type === 'blue' && <Blue />}
18 </>
19 );
20}
符号 .
被称为 可选链接。如果值存在,则返回值。否则,它会返回 undefined
。
当你这样做时,浏览器将更新,并将渲染不同的鲸鱼:
访问 URL 参数
搜索参数工作,但他们在这种情况下不是最好的解决方案. 一般来说,你会使用搜索参数来改进页面:转换信息或加载特定的数据. 在这种情况下,你不是改进页面;你正在创建一个新的静态页面。
打开App.js
:
1nano src/components/App/App.js
相反,你会将鲸鱼信息作为搜索,然后将其直接添加到URL本身,这意味着你会将鲸鱼移动到URL中,而不是在一个?
之后添加它。
1[label router-tutorial/src/components/App/App.js]
2import React from 'react';
3import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
4import './App.css';
5
6import Manatee from '../Manatee/Manatee';
7import Narwhal from '../Narwhal/Narwhal';
8import Whale from '../Whale/Whale';
9
10function App() {
11 return (
12 <div className="wrapper">
13 <h1>Marine Mammals</h1>
14 <BrowserRouter>
15 <nav>
16 <ul>
17 <li><Link to="/manatee">Manatee</Link></li>
18 <li><Link to="/narwhal">Narwhal</Link></li>
19 <li><Link to="/whale">Whale</Link></li>
20 <li><Link to="/whale/beluga">Beluga Whale</Link></li>
21 <li><Link to="/whale/blue">Blue Whale</Link></li>
22 </ul>
23 </nav>
24 <Switch>
25 <Route path="/manatee">
26 <Manatee />
27 </Route>
28 <Route path="/narwhal">
29 <Narwhal />
30 </Route>
31 <Route path="/whale">
32 <Whale />
33 </Route>
34 </Switch>
35 </BrowserRouter>
36 </div>
37 );
38}
39
40export default App;
现在你需要创建一个新的路线,可以捕捉/whale/beluga
和/whale/blue
。你可以手动添加它们,但这不会在没有提前了解所有可能性的情况下工作,例如当你有一个用户列表或其他动态数据时。
代替为每个路径创建路径,请将 URL 参数添加到当前路径中。 URL 参数是带有 kolon 的关键字。 React Router 将该参数用作 wildcard,并将匹配包含该模式的任何路径。
在这种情况下,创建一个关键字的 :类型
. 完整的 路径
将是 /whale/:type
. 这将匹配任何路径,以 /whale
开头,并将存储变量信息的参数变量称为 type
. 这条路径不会匹配 /whale
,因为它不包含额外的参数。
您可以添加/whale
作为新路线之后的路线,或者您可以使用准确
关键字在/whale/:type
路线前添加它。
添加/whale/:type
的新路线,并为当前路线添加一个准确
属性:
1[label router-tutorial/src/components/App/App.js]
2import React from 'react';
3import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
4import './App.css';
5
6import Manatee from '../Manatee/Manatee';
7import Narwhal from '../Narwhal/Narwhal';
8import Whale from '../Whale/Whale';
9
10function App() {
11 return (
12 <div className="wrapper">
13 <h1>Marine Mammals</h1>
14 <BrowserRouter>
15 <nav>
16 <ul>
17 <li><Link to="/manatee">Manatee</Link></li>
18 <li><Link to="/narwhal">Narwhal</Link></li>
19 <li><Link to="/whale">Whale</Link></li>
20 <li><Link to="/whale/beluga">Beluga Whale</Link></li>
21 <li><Link to="/whale/blue">Blue Whale</Link></li>
22 </ul>
23 </nav>
24 <Switch>
25 <Route path="/manatee">
26 <Manatee />
27 </Route>
28 <Route path="/narwhal">
29 <Narwhal />
30 </Route>
31 <Route exact path="/whale">
32 <Whale />
33 </Route>
34 <Route path="/whale/:type">
35 <Whale />
36 </Route>
37 </Switch>
38 </BrowserRouter>
39 </div>
40 );
41}
42
43export default App;
现在您正在传输新信息,您需要访问它并使用该信息来渲染动态组件。
打开Whale.js
:
1nano src/components/Whale/Whale.js
导入useParams
链接,将连接到您的路由器并将任何 URL 参数拉到对象中。 摧毁对象以将类型
字段拉出来。 删除解析搜索
的代码,并使用参数来条件性地渲染儿童组件:
1[label router-tutorial/src/components/Whale/Whale.js]
2import React from 'react';
3import { useParams } from 'react-router-dom';
4import Beluga from './Beluga';
5import Blue from './Blue';
6
7export default function Whale() {
8 const { type } = useParams();
9
10 return (
11 <>
12 <h2>Whale</h2>
13 {type === 'beluga' && <Beluga />}
14 {type === 'blue' && <Blue />}
15 </>
16 );
17}
当你这样做时,浏览器将更新,你将能够使用新的URL,如 http://localhost:3000/whale/beluga
:
URL参数是传递条件数据的一个清晰的方法,它们并不像搜索参数一样灵活,可以组合或重新排序,但它们更清晰,搜索引擎更容易索引。
在此步骤中,您使用搜索参数和 URL 参数传输了变量数据,您还使用了useLocation
和useParams
链接来提取信息并渲染条件组件。
但是有一个问题:路线列表越来越长,你开始接近/whale
和/whale/:type
路线的重复。 React Router 允许你将儿童路线直接分成组件,这意味着你不需要将整个列表放在一个组件中。
步骤4 - 固定路线
React Router 使用嵌入式路由器,在儿童组件中渲染更具体的路由信息. 在此步骤中,您将使用嵌入式路由器并在不同的组件中添加路由器。
在最后一步中,您在App.js
中添加了路线,这有一些优点:它将所有路线放在一个地方,基本上为您的应用程序创建一个网站地图,但它可以很容易增长,难以读取和维护。
打开App.js
:
1nano src/components/App/App.js
删除/whale/:type
路线,并删除准确
路线,以便您只有一条鲸鱼路线:
1[label router-tutorial/src/components/App/App.js]
2import React from 'react';
3import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
4import './App.css';
5
6import Manatee from '../Manatee/Manatee';
7import Narwhal from '../Narwhal/Narwhal';
8import Whale from '../Whale/Whale';
9
10function App() {
11 return (
12 <div className="wrapper">
13 <h1>Marine Mammals</h1>
14 <BrowserRouter>
15 <nav>
16 <ul>
17 <li><Link to="/manatee">Manatee</Link></li>
18 <li><Link to="/narwhal">Narwhal</Link></li>
19 <li><Link to="/whale">Whale</Link></li>
20 <li><Link to="/whale/beluga">Beluga Whale</Link></li>
21 <li><Link to="/whale/blue">Blue Whale</Link></li>
22 </ul>
23 </nav>
24 <Switch>
25 <Route path="/manatee">
26 <Manatee />
27 </Route>
28 <Route path="/narwhal">
29 <Narwhal />
30 </Route>
31 <Route path="/whale">
32 <Whale />
33 </Route>
34 </Switch>
35 </BrowserRouter>
36 </div>
37 );
38}
39
40export default App;
保存并关闭文件。
接下来,打开Whale.js
,在这里您将添加嵌入式路线。
1nano src/components/Whale/Whale.js
您需要做两件事:首先,使用useRouteMatch
取当前路径;接下来,渲染新的<Switch>
和<Route>
组件以显示正确的组件。
导入 useRouteMatch
. 这将返回包含 path
和 url
的对象. 摧毁对象以获取 path
。
1[label router-tutorial/src/components/Whale/Whale.js]
2import React from 'react';
3import { useRouteMatch } from 'react-router-dom';
4import Beluga from './Beluga';
5import Blue from './Blue';
6
7export default function Whale() {
8 const { path } = useRouteMatch();
9
10 return (
11 <>
12 <h2>Whale</h2>
13 {type === 'beluga' && <Beluga />}
14 {type === 'blue' && <Blue />}
15 </>
16 );
17}
接下来,导入Switch
和Route
,以便你可以添加新的路线。你的新路线将与你在App.js
中创建的路线相同,但你不需要用BrowserRouter
包装它们。添加新路线,但用path
先定路线。
1[label router-tutorial/src/components/Whale/Whale.js]
2import React from 'react';
3import { Switch, Route, useRouteMatch } from 'react-router-dom';
4import Beluga from './Beluga';
5import Blue from './Blue';
6
7export default function Whale() {
8 const { path } = useRouteMatch();
9 return (
10 <>
11 <h2>Whale</h2>
12 <Switch>
13 <Route path={`${path}/beluga`}>
14 <Beluga />
15 </Route>
16 <Route path={`${path}/blue`}>
17 <Blue />
18 </Route>
19 </Switch>
20 </>
21 );
22}
当你这样做时,浏览器将更新,你将能够访问儿童路线。
这是一个额外的代码,但它保持了孩子的路线与他们的父母一起。不是所有的项目都使用嵌套路线:有些人喜欢有一个明确的列表。这是一个团队偏好和一致性的问题。
在此步骤中,您已将嵌入式路径添加到项目中,您已使用useRouteMatch
口袋将当前路径拉出来,并在组件中添加新的路径,以使基础组件中的新组件。
结论
React Router 是任何 React 项目的重要组成部分,当您构建单页应用程序时,您将使用路径将应用程序分为可用的零件,用户可以轻松和一致地访问。
当您开始将组件划分为路径时,您将能够利用 代码划分,通过查询参数保存状态,以及其他工具来改善用户体验。
如果您想阅读更多 React 教程,请查看我们的 React 主题页面,或返回 如何在 React.js 系列中编码页面。