React is a JavaScript library for building user interfaces. We can also extend it to build multi-page applications with the help of React Router. This is a third-party library that enables routing in our React apps.
React是一个用于构建用户界面JavaScript库。 我们还可以借助React Router将其扩展为构建多页应用程序。 这是一个第三方库,可在我们的React应用程序中进行路由。
In this tutorial, we are going to cover everything you need to know to get started with React Router.
在本教程中,我们将介绍使用React Router入门所需的一切。
Setting up the project
设置项目
What is routing?
什么是路由?
Setting up the router
设置路由器
Rendering routes
渲染路线
Using Links to switch pages
使用链接切换页面
Passing Route parameters
传递路线参数
Navigating programmatically
以编程方式导航
Redirecting to another page
重定向到另一个页面
Redirecting to a 404 page
重定向到404页面
Guarding routes
护路
Router Hooks
路由器挂钩
useHistory
使用历史
useParams
useParams
useLocation
useLocation
Final Thoughts
最后的想法
Next Steps
下一步
To be able to follow along, you will need to create a new React app by running the following command in your terminal:
为了能够继续学习,您需要通过在终端中运行以下命令来创建新的React应用程序:
npx create-react-app react-router-guide
Then, add these lines of code to the App.js
file:
然后,将以下代码行添加到App.js
文件中:
import React from "react";
import "./index.css"
export default function App() {
return (
);
}
// Home Page
const Home = () => (
Home
);
// About Page
const About = () => (
About
);
// Contact Page
const Contact = () => (
Contact
);
const FakeText = () => (
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
)
Then, if you're ready to go, let's start by answering an important question: what is routing?
然后,如果您准备好出发,我们首先回答一个重要问题:什么是路由?
Routing is the capacity to show different pages to the user. That means the user can move between different parts of an application by entering a URL or clicking on an element.
路由是向用户显示不同页面的能力。 这意味着用户可以通过输入URL或单击元素来在应用程序的不同部分之间移动。
As you may already know, by default, React comes without routing. And to enable it in our project, we need to add a library named react-router.
您可能已经知道,默认情况下,React不带路由。 为了在我们的项目中启用它,我们需要添加一个名为react-router的库。
To install it, you will have to run the following command in your terminal:
要安装它,您将必须在终端中运行以下命令:
yarn add react-router-dom
Or
要么
npm install react-router-dom
Now, we've successfully installed our router, let's start using it in the next section.
现在,我们已经成功安装了路由器,让我们在下一部分开始使用它。
To enable routing in our React app, we first need to import BrowserRouter
from react-router-dom
.
要在React应用中启用路由,我们首先需要从react-router-dom
导入BrowserRouter
。
In the App.js
file, enter the following:
在App.js
文件中,输入以下内容:
import React, { Fragment } from "react";
import "./index.css"
import { BrowserRouter as Router } from "react-router-dom";
export default function App() {
return (
);
}
This should hold everything in our app where routing is needed. That means, if we need routing in our entire app, we must wrap our higher component with BrowserRouter
.
这应该在我们需要路由的应用程序中保存所有内容。 这意味着,如果需要在整个应用程序中进行路由,则必须使用BrowserRouter
包装更高的组件。
By the way, you don't have to rename BrowserRouter as Router
as I do here, I just want to keep things readable.
顺便说一句,您不必像我在这里那样将BrowserRouter as Router
重命名BrowserRouter as Router
,我只是想保持可读性。
A router alone doesn't do much. So let's add a route in the next section.
路由器本身并不能做很多事情。 因此,让我们在下一部分中添加一条路线。
To render routes, we have to import the Route
component from the router package.
要渲染路由,我们必须从路由器包中导入Route
组件。
In your App.js
file, add the following code:
在您的App.js
文件中,添加以下代码:
import React, { Fragment } from "react";
import "./index.css"
import { BrowserRouter as Router, Route } from "react-router-dom";
export default function App() {
return (
Welcome!
} />
);
}
Then, add it where we want to render the content. The Route
component has several properties. But here, we just need path
and render
.
然后,将其添加到我们要呈现内容的位置。 Route
组件具有多个属性。 但是在这里,我们只需要path
和render
。
path
: the path of the route. Here, we use /
to define the path of the home page.
path
:路线的路径。 在这里,我们使用/
定义主页的路径。
render
: will display the content whenever the route is reached. Here, we'll render a welcome message to the user.
render
:在到达路线时将显示内容。 在这里,我们将向用户呈现欢迎消息。
In some cases serving routes like that is perfectly fine. But imagine a case when we have to deal with a real component – using render
may not be the right solution.
在某些情况下,提供这样的路线非常好。 但是想象一下当我们不得不处理一个真实组件的情况–使用render
可能不是正确的解决方案。
So, how can we display a real component? Well, the Route
component has another property named component
.
那么,我们如何显示真实的组件? 好吧, Route
组件还有另一个名为component
属性。
Let's update our example a bit to see it in action.
让我们对示例进行一些更新以了解其实际效果。
In your App.js
file, add the following code:
在您的App.js
文件中,添加以下代码:
import React, { Fragment } from "react";
import "./index.css"
import { BrowserRouter as Router, Route } from "react-router-dom";
export default function App() {
return (
);
}
const Home = () => (
Home
);
Now, instead of rendering a message, our route will load the Home
component.
现在,无需渲染消息,我们的路线将加载Home
组件。
To get the full power of React Router, we need to have multiple pages and links to play with. We already have pages (components if you want, too), so now let's add some links so we can switch between pages.
要获得React Router的全部功能,我们需要有多个页面和链接可供使用。 我们已经有页面(如果需要,也可以包含组件),所以现在让我们添加一些链接,以便我们可以在页面之间进行切换。
To add links to our project, we will use the React Router again.
要添加到我们项目的链接,我们将再次使用React Router。
In your App.js
file, add the following code:
在您的App.js
文件中,添加以下代码:
import React, { Fragment } from "react";
import "./index.css"
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
export default function App() {
return (
);
}
const Home = () => (
Home
);
const About = () => (
About
);
const Contact = () => (
Contact
);
After importing Link
, we have to update our navigation bar a bit. Now, instead of using a
tag and href
, React Router uses Link
and to
to, well, be able to switch between pages without reloading it.
导入Link
,我们必须稍微更新导航栏。 现在,而不是使用a
标签和href
,阵营路由器使用Link
,并to
对,很好,能够在不重新加载页面它之间进行切换。
Then, we need to add two new routes, About
and Contact
, to be able to switch between pages or components.
然后,我们需要添加两个新的路线, About
和Contact
,以便能够在页面或组件之间进行切换。
Now, we can go to different parts of our app through links. But there is an issue with our router: the Home
component is always displayed even if we switch to other pages.
现在,我们可以通过链接转到应用程序的不同部分。 但是我们的路由器存在一个问题:即使我们切换到其他页面,也会始终显示Home
组件。
This is because React Router will check if the path
defined starts with /
. If that's the case, it will render the component. And here, our first route starts with /
, so the Home
component will be rendered each time.
这是因为React Router将检查定义的path
是否以/
开头。 如果是这样,它将渲染组件。 在这里,我们的第一条路线以/
开头,因此每次都会渲染Home
组件。
However, we can still change the default behavior by adding the exact
property to Route
.
但是,我们仍然可以通过将exact
属性添加到Route
来更改默认行为。
In App.js
, add:
在App.js
,添加:
By updating the Home
route with exact
, now it will be rendered only if it matches the full path.
通过使用exact
更新Home
路线,现在仅当它与完整路径匹配时才会呈现。
We can still enhance it by wrapping our routes with Switch
to tell to React Router to load only one route at a time.
我们仍然可以通过使用Switch
包装路由来告诉React Router一次只加载一条路由来增强它。
In App.js
, add:
在App.js
,添加:
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
Now that we have new links, let's use them to pass parameters.
现在我们有了新的链接,让我们使用它们来传递参数。
To pass data between pages, we have to update our example.
要在页面之间传递数据,我们必须更新示例。
In your App.js
file, add the following code:
在您的App.js
文件中,添加以下代码:
import React, { Fragment } from "react";
import "./index.css"
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
export default function App() {
const name = 'John Doe'
return (
);
}
const Home = () => (
Home
);
const About = ({match:{params:{name}}}) => (
// props.match.params.name
About {name}
);
const Contact = () => (
Contact
);
As you can see here, we start by declaring a new constant name
which will be passed as a parameter to the About
page. And we append name
to the corresponding link.
如您在此处看到的,我们首先声明一个新的常量name
,该常量name
将作为参数传递给“ About
页面。 然后,将name
附加到相应的链接。
With that, we now have to update the About
route by adjusting its path to receive name
as a parameter path="/about/:name"
.
这样,我们现在必须通过调整其路径以将name
接收为参数path="/about/:name"
来更新About
路线。
Now, the parameter will be received as props from the About
component. The only thing we have to do now is destructure the props and get back the name
property. By the way, {match:{params:{name}}}
is the same as props.match.params.name
.
现在,参数将从About
组件作为道具接收。 现在我们唯一要做的就是销毁道具并取回name
属性。 顺便说一下, {match:{params:{name}}}
与props.match.params.name
相同。
We've done a lot up to this point. But in some cases we don't want to use links to navigate between pages.
到目前为止,我们已经做了很多工作。 但是在某些情况下,我们不想使用链接在页面之间导航。
Sometimes, we have to wait for an operation to finish before navigating to the next page.
有时,我们必须等待操作完成才能导航到下一页。
So, let's handle that case in the next section.
因此,让我们在下一部分中处理这种情况。
The props we receive have some convenient methods we can use to navigate between pages.
我们收到的道具有一些便捷的方法可用于在页面之间导航。
In App.js
, add:
在App.js
,添加:
const Contact = ({history}) => (
Contact
);
Here, we pull the history
object from the props we receive. It has some handy methods like goBack
, goForward
, and so on. But here, we will use the push
method to be able to go to the Home page.
在这里,我们从收到的道具中提取history
对象。 它具有一些方便的方法,如goBack
, goForward
等。 但是在这里,我们将使用push
方法来转到主页。
Now, let's handle the case when we want to redirect our user after an action.
现在,让我们处理在操作后想要重定向用户的情况。
The React Router has another component named Redirect
. As you guessed, it helps us redirect the user to another page
React Router具有另一个名为Redirect
组件。 您猜到了,它可以帮助我们将用户重定向到另一个页面
In App.js
, add:
在App.js
,添加:
import { BrowserRouter as Router, Route, Link, Switch, Redirect } from "react-router-dom";
const About = ({match:{params:{name}}}) => (
// props.match.params.name
{ name !== 'John Doe' ? : null }
About {name}
);
Now, if the name
passed as a parameter is not equal to John Doe
, the user will be redirected to the home page.
现在,如果作为参数传递的name
不等于John Doe
,则用户将被重定向到主页。
You could argue that you should redirect the user with props.history.push('/)
. Well, the Redirect
component replaces the page and therefore the user can't go back to the previous page. But, with the push method they can. However, you can use props.history.replace('/)
to mimic the Redirect
behavior.
您可能会争辩说应该使用props.history.push('/)
重定向用户。 好吧, Redirect
组件将替换页面,因此用户无法返回上一页。 但是,使用push方法可以。 但是,您可以使用props.history.replace('/)
来模仿Redirect
行为。
Now let's move on and handle the case when the user hits a route that doesn't exist.
现在让我们继续处理当用户点击一条不存在的路线时的情况。
To redirect the user to a 404 page, you can create a component to show it. But here, to keep things simple, I will just display a message with render
.
要将用户重定向到404页面,您可以创建一个组件来显示它。 但是在这里,为了简单起见,我将只显示一条带有render
的消息。
import React, { Fragment } from "react";
import "./index.css"
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
export default function App() {
const name = 'John Doe'
return (
404: page not found
} />
);
}
The new route we've added will catch every path that doesn't exist and redirect the user to the 404 page.
我们添加的新路由将捕获所有不存在的路径,并将用户重定向到404页面。
Now, let's move on and learn how to protect our routes in the next section.
现在,让我们继续前进,并在下一部分中学习如何保护我们的路线。
There are many ways to protect routes to React. But here I will just check if the user is authenticated and redirect them to the appropriate page.
有很多方法可以保护通往React的路由。 但是在这里,我将仅检查用户是否已通过身份验证并将他们重定向到适当的页面。
import React, { Fragment } from "react";
import "./index.css"
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
export default function App() {
const name = 'John Doe'
const isAuthenticated = false
return (
{
isAuthenticated ?
<>
> :
}
);
}
As you can see here, I declared a variable to mimic authentication. Then, check if the user is authenticated or not. If they are, render protected pages. Otherwise redirect them to the home page.
如您在这里看到的,我声明了一个模仿身份验证的变量。 然后,检查用户是否已通过身份验证。 如果是这样,请呈现受保护的页面。 否则,将它们重定向到主页。
We've covered a lot up to this point, but an interesting part remains: router hooks.
到目前为止,我们已经介绍了很多内容,但是有趣的部分仍然存在:路由器挂钩。
Let's move to the final section and introduce Hooks.
让我们进入最后一部分,介绍Hooks。
Router hooks make things much easier. Now you can access the history, location, or parameters in an easy and elegant way.
路由器挂钩使事情变得容易得多。 现在,您可以轻松,优雅地访问历史记录,位置或参数。
The useHistory
hook gives us access to the history instance without pulling it from props.
useHistory
挂钩使我们可以访问历史实例,而无需从道具中将其提取。
import { useHistory } from "react-router-dom";
const Contact = () => {
const history = useHistory();
return (
Contact
)
};
This hook helps us get the parameter passed on the URL without using the props object.
这个钩子帮助我们无需使用props对象就可以在URL上传递参数。
import { BrowserRouter as Router, Route, Link, Switch, useParams } from "react-router-dom";
export default function App() {
const name = 'John Doe'
return (
);
}
const About = () => {
const { name } = useParams()
return (
// props.match.params.name
{ name !== 'John Doe' ? : null }
About {name}
)
};
This hook returns the location object that represents the current URL.
该挂钩返回代表当前URL的位置对象。
import { useLocation } from "react-router-dom";
const Contact = () => {
const { pathname } = useLocation();
return (
Contact
Current URL: {pathname}
)
};
React Router is an amazing library that helps us go from a single page to a multi-page application feeling with great usability. (Just keep in mind – at the end of the day, it's still a single page app).
React Router是一个了不起的库,它可以帮助我们从一个页面转到一个多页面的应用程序,并具有很高的可用性。 (请记住-归根结底,它仍然是单页应用程序)。
And now with router hooks, you can see how easy and elegant they are. They're definitely something to consider in your next project.
现在有了路由器挂钩,您可以看到它们多么简单和优雅。 它们绝对是您下一个项目中要考虑的东西。
You can read more of my articles on my blog.
您可以在我的博客上阅读更多我的文章。
React Router Documentation
React Router文档
Photo by Joshua Sortino on Unsplash
Joshua Sortino在Unsplash上拍摄的照片
翻译自: https://www.freecodecamp.org/news/a-complete-beginners-guide-to-react-router-include-router-hooks/