In this article, we'll cover the important things you can quickly learn to be informed and confident with using and conversing on React Router v4.
在本文中,我们将介绍您可以快速学习的重要内容,以便在React Router v4上进行使用和交谈时了解并充满信心。
什么是React Router? (What is React Router?)
React Router is a client-side router (CSR) for use with React projects (I know, duh right?). It provides routing which is the fancy term for the rendering of different components depending on URL paths within a React web application.
React Router是用于React项目的客户端路由器(CSR)( 我知道,对吗? )。 它提供了路由 ,这是根据React Web应用程序中URL路径呈现不同组件的理想术语。
一个如何安装和使用? (How does one install and use?)
Run the following command in your project to save react-router-dom
as a project dependency:
在您的项目中运行以下命令,以将react-router-dom
保存为项目依赖项:
npm i -S react-router-dom
Using the ES2015 syntax, you can import React Router into your React components using:
使用ES2015语法,可以使用以下命令将React Router导入到React组件中:
import * from 'react-router-dom'
设置基本路线 (Setting up your basic routes)
Link
components can be thought of as your typical anchor links that, when clicked, redirect the user to the path specified in its to
property.
Link
组件可以看作是典型的锚点链接,单击它们后,会将用户重定向到其to
属性中指定的路径。
Route
components can be thought of as the controller for the render. When you see these components, just think this is what they say:
Route
组件可以视为渲染的控制器。 当您看到这些组件时,请以为这是它们的意思:
WHEN I see the URL as what is specified in my path
property, THEN I will render the component listed in my component
or render
property.
当我看到在 path
属性中 指定的URL时 ,那么我将呈现 component
或 render
属性中 列出的 component
。
The basic example below is mostly lifted from ReactTraining’s basic example:
以下基本示例大部分是从ReactTraining的基本示例中提出的 :
嵌套路线 (Nesting Routes)
Nesting routes is exactly the same as creating high-level routes, except for defining a BrowserRouter
component (as your nested routes are composed within the high-level BrowserRouter
component anyway). It simply needs more Link
and Route
components. We can indefinitely nest further routes within any other nested routes.
嵌套路由与创建高级路由完全相同,只是定义了BrowserRouter
组件(因为嵌套的路由BrowserRouter
是在高级BrowserRouter
组件内组成的)。 它只需要更多的Link
和Route
组件。 我们可以在其他任何嵌套路由中无限期嵌套其他路由。
传递URL参数 (Passing URL parameters)
In the previous example, we had different components defined for each topic in nested routes. In the following example, we have a single Topic
component that is rendered for the three different routes. The Topic
component dynamically renders the topicId
, which is passed as a property by the Route
, and its value defined as part of the URL using the :
.
在前面的示例中,我们为嵌套路由中的每个主题定义了不同的组件。 在下面的示例中,我们为三个不同的路线呈现了一个Topic
组件。 Topic
组件动态地呈现topicId
(由Route
作为属性传递),并使用:
将其值定义为URL的一部分。
When a Route
defines a component to render, it passes a match
object to its props (along with location
and history
, but unimportant for now). This match
object has a params
object which contains any variables passed by Route
defined using the :
notation in the path
URL (aka Route Parameter).
当Route
定义要渲染的组件时,它将match
对象传递到其props(以及location
和history
,但暂时不重要)。 此match
对象有一个params
对象,其中包含由Route
传递的任何变量,这些变量使用path
URL中的:
表示法(也称为Route参数)定义。
In this way, we can cut down on separately creating components for each Link
and instead make one re-usable component rendered with the information passed to it.
通过这种方式,我们可以减少为每个Link
单独创建的组件,而是使一个可重用的组件与传递给它的信息一起呈现。
避免硬编码嵌套链接 (Avoiding hard-coding nested links)
When creating nested links, our Link
component still needs to refer to the entire URL path instead of the location it’s really concerned with. This means that nested links would have hard-coded locations to its parent links, which isn’t great when a name change occurs and a big renaming effort is required.
创建嵌套链接时,我们的Link
组件仍然需要引用整个URL路径,而不是它真正关心的位置。 这意味着嵌套链接将对其父链接具有硬编码的位置,当名称发生更改并且需要大量的重命名工作时,这并不是很好。
Instead, using the match
object passed by Route
, we can dynamically refer to it’s location and use that to avoid hard-coding.
相反,使用Route
传递的match
对象,我们可以动态地引用它的位置,并使用它来避免硬编码。
For example:<Route path="/topics" component={Topics
}/> passes a
match object with
a url property with the value "/t
opics" .
Topics , via its props, can reuse the mat
ch.url when defining its nested links.
例如: <Route path="/topics" component={Topics
} /> PAS ses a
匹配对象瓦特ith
与所述的URL属性value "/t
OPI cs" .
的主题,通过其道具,可以雷乌斯e the mat
限定其嵌套链接时ch.url。
避免模棱两可的比赛 (Avoiding ambiguous matches)
By default, when you specify Route
components, each matching path will be rendered inclusively. Using URL parameters, this becomes problematic. As the parameter effectively acts as a wildcard (so any text is found as matching), you will find that when these are mixed with hard-coded routes, they both will display. Using exact
won’t help either.
默认情况下,当您指定Route
组件时, 每个匹配的路径都将被包含在内 。 使用URL参数,这将成为问题。 由于该参数有效地充当了通配符(因此可以找到任何匹配的文本),您会发现当这些参数与硬编码的路由混合使用时,它们都将显示。 使用exact
也无济于事。
React Router’s solution is the Switch
component. The Switch
component will render the child Route
component on the first matching path exclusively. This means that if all hard-coded routes are specified first, then these will be rendered only.
React Router的解决方案是Switch
组件。 Switch
组件将仅在第一个匹配路径上呈现子Route
组件。 这意味着,如果首先指定所有硬编码的路由,则将仅呈现这些路由。
多路线渲染 (Multiple Route Rendering)
There are times when you don’t want ambiguous matching of Route
components, but there will be times when you do.
有时候,您不希望Route
组件进行模棱两可的匹配,但有时您会想要。
Remembering that we can think of Route
as a simple “WHEN I see this path, THEN render this component”, which means we can have multiple Route
components matching a single page, but providing different content.
记住,我们可以将Route
视为简单的“ 当我看到此路径时,然后渲染此组件 ”,这意味着我们可以有多个Route
组件匹配单个页面,但提供不同的内容。
In the below example, we use one component to pass the URL parameter to show the user their current path, and another component that renders with the content component. That means two different components are rendered for the one URL path.
在下面的示例中,我们使用一个组件传递URL参数以向用户显示其当前路径,并使用另一个与内容组件一起呈现的组件。 这意味着为一个URL路径呈现两个不同的组件。
直接从Route渲染 (Rendering from Route directly)
A Route
component can be passed a component
to render if one is available. It can also render a component directly using the render
property.
可以将Route
组件传递给要渲染的component
(如果有)。 它还可以使用render
属性直接渲染组件。
<Route exact path={url} render={ () => <h3>Please select a topic</h3>} />
使用Route将属性传递给组件 (Passing properties to a component using Route)
URL passed parameters are fine, but what about passing in properties that require more data to components, such as objects? Route
doesn’t allow you to append properties it doesn’t recognize.
URL传递的参数很好,但是如何将需要更多数据的属性传递给对象(如对象)呢? Route
不允许您添加它无法识别的属性。
<Route exact path="/" component={Home} doSomething={() => "doSomething" } /> // doesn't work
However what can be done to pass properties is to use Route
render method.
但是,可以通过传递属性的方法是使用Route
渲染方法。
<Route exact path="/" render={(props) => <Home {...props} doSomething={() => "doSomething"} />
使用链接将属性传递给组件 (Passing properties to a component using Link)
You can also pass properties to a component via the Link
component. Instead of passing in a String to the to
property, we can pass in an object instead. On this object, we can declare the pathname
representing to URL we want to navigate to. We also declare a state
object that contains any custom properties we want. These properties are contained on the location
object (in location.state
).
您还可以通过Link
组件将属性传递给组件。 除了将String传递给to
属性之外,我们还可以传递一个对象。 在此对象上,我们可以声明表示要导航到的URL的pathname
。 我们还声明了一个state
对象,其中包含我们想要的任何自定义属性。 这些属性包含在location
对象中(位于location.state
)。
In the below example (contrived, I know…), we pass in a message property to display on a page.
在下面的示例中( 我知道,是作作的…… ),我们传入了message属性以显示在页面上。
重定向-使用重定向 (Redirection — Using Redirect)
You can use the Redirect
component to redirect the users’ immediate URL to another.
您可以使用Redirect
组件将用户的即时URL重定向到另一个。
In the below example, we see a redirect for a user depending on whether the isAuthenticated
state on component RedirectExample
is true or false, appropriately redirecting if they’re logged in (to /home) or logged out (to /dashboard):
在下面的示例中,我们根据组件RedirectExample
上的isAuthenticated
状态是true还是false来查看用户的重定向,如果用户登录(登录到/ home或登出(登录到/ dashboard ),则进行适当的重定向:
重定向-使用withRouter() (Redirection — Using withRouter())
Another way to redirect is by using the higher-order component withRouter
. This allows you to pass the properties of Route
(match
, location
, and importantly in this example history
) to components that aren’t rendered via the typical Route
component. We do this by wrapping our exported component with the withRouter
.
重定向的另一种方法是使用withRouter
的高阶组件。 这使您可以将Route
的属性( match
, location
,并且在本示例中为history
),传递给那些不是通过典型Route
组件呈现的组件。 为此,我们使用withRouter
包装导出的组件。
Why is having history
important? We can use history
to force redirection by pushing a URL to the history
object.
为什么拥有history
很重要? 我们可以使用history
通过将URL推送到history
对象来强制重定向。
There are caveats to this way of routing which I don’t detail (see the withRouter documentation). Also, the exported component must still be composed within another component that is rendering withinBrowserRouter
(which I don’t show in this example).
有一些关于这种路由方式的警告,我没有详细介绍(请参阅withRouter文档 )。 同样,导出的组件必须仍然由另一个在BrowserRouter
呈现的组件组成(在本示例中未显示)。
默认路由组件 (Default Route Component)
There will be times when a Link
may refer to a URL that has no corresponding <Route path='/something' component={Something
}/> . Or a user will type an incorrect URL in the browser bar.
有时, Link
可能引用的URL没有相应的<Route path='/something' component={Something
} />。 否则,用户将在浏览器栏中键入错误的URL。
When that happens, all we will have is a non-responsive page or link where nothing happens (which is not as bad as actually being navigated to a non-existent page).
发生这种情况时,我们将拥有一个无响应的页面或链接,其中什么也没有发生(这不像实际导航到不存在的页面那样糟糕)。
Most times we want to at least show the user we can’t find their content, maybe with a witty image like Github’s 404 page. In this case, you’ll want a default component, also known as a no-match or catch-all component.
大多数时候,我们至少希望向用户显示我们找不到他们的内容,也许带有一个像Github的404 page这样的机智图像。 在这种情况下,您需要一个默认组件,也称为不匹配或包罗万象的组件。
When a user clicks a link (or indeed types something incorrectly in the browser navigation bar), so long as there are no other matching components, we will be directed to the default component to be rendered.
当用户单击链接(或者确实在浏览器导航栏中键入错误)时,只要没有其他匹配的组件,我们将被定向到要呈现的默认组件。
Note the use of Switch
(ambiguous matching with URL parameters). As this Route
has no path, it will be effectively always rendered. We require a Switch
to only render if it cannot find any other matching Route
path’s.
请注意Switch
的使用(与URL参数的模糊匹配)。 由于此Route
没有路径,因此将始终有效地进行渲染。 我们要求Switch
仅在找不到其他匹配的Route
路径时才渲染。
自订连结 (Custom Links)
The Link
component at its core renders an anchor element for whatever is passed as its to
property. There are times when we would want customizations made to the Link component without having to have these customizations everywhere. React Router allows a means of doing this is by creating a custom link (see React Router training guide for more info — we use their example more or less below).
该Link
的核心组件呈现为无论是作为其传递了一个锚元素to
财产。 有时候,我们希望对链接组件进行自定义,而不必到处都有这些自定义。 React Router允许通过创建自定义链接来实现此目的(有关更多信息,请参见React Router培训指南 -我们在下面或多或少使用它们的示例)。
For a custom link, one is essentially wrapping the existing Link
component inside a custom component, and providing additional information, not unlike the Higher Order Component pattern.
对于自定义链接,实质上是将现有Link
组件包装在一个自定义组件中,并提供其他信息,这与“ 高阶组件”模式不同 。
In our example, we only show the links for the pages that aren’t displayed. For our CustomLink
component to have the knowledge of what page is currently displayed, we need to wrap the Link
component in a Route
component so that we can pass the match
object that comes with React Router’s Route
. We pass this wrapping our Link
component as a child to the Route
component.
在我们的示例中,我们仅显示未显示页面的链接。 为了使CustomLink
组件了解当前显示的页面,我们需要将Link
组件包装在Route
组件中,以便我们可以传递React Router的Route
附带的match
对象。 我们将此包装作为子级的Link
组件传递给Route
组件。
Route, if you remember, simply checks the current path and when we match, will render “something” (either defined by the component
/render
properties or as as a child of Route
— such as our Link component).
记住,Route仅检查当前路径,当我们匹配时,将渲染“内容”(由component
/ render
属性定义,或作为Route
的子代-例如我们的Link组件)。
We subvert this slightly with an equality check to say if we don’t find a match
object (if our current path doesn’t match what’s defined in the path
property in the Route
declared in CustomLink
), then render a Link
, otherwise render nothing.
我们用相等性检查稍微颠覆这一点,以说是否找不到match
对象(如果当前路径与CustomLink
声明的Route
的path
属性中定义的内容不匹配),则呈现Link
,否则不呈现任何内容。
解析查询字符串 (Parsing Query Strings)
Query strings are parameters in the URL that look like variables and are prefixed by the question mark (such as www.example.com/search?name=Greg
).
查询字符串是URL中看起来像变量的参数,并带有问号(例如www.example.com/search?name=Greg
)作为前缀。
I’m going to rip the band-aid off quick — React Router doesn’t come with a way to parse query strings ?. It does, however, locate query strings as a String in its passed properties, within location.search,
wherein the above example would be defined as search: "?name=Greg".
我将快速取消创可贴— React Router并没有解析查询字符串的方法? 但是,它确实在ocation.search,
查询字符串定位为String,位于其传递的属性中ocation.search,
其中上面的示例将定义为ocation.search,
earch: "?name=Greg".
So what to do? There are a number of ways to solve this problem, including reinventing the wheel. I would like to anecdotally highlight the npm package query string as a solution which I’ve used and has become my de facto query string parser.
那么该怎么办? 解决这个问题的方法有很多,包括重新发明轮子。 我想轶事地强调npm包查询字符串作为我已经使用的解决方案,它已经成为我事实上的查询字符串解析器。
过渡时提示用户 (Prompting users when transitioning)
React Router v4 comes with a Prompt
component, which as you can guess, displays a prompt to the user. This is useful as UX feature for users when they are warned of potentially losing form data if they transition from the current form page.
React Router v4带有一个Prompt
组件,您可以猜到,它向用户显示提示。 当警告用户从当前表单页面过渡时可能丢失表单数据时,此功能可用作UX功能。
The basic pattern in implementing a navigational prompt is to have a boolean state property which decides whether they should be prompted or not. This state is updated via the form based on whether there are values selected for any form field. Within the form, you render a Prompt
component, passing in two properties: a when
(which is your boolean state set earlier) and a message
to display.
实施导航提示的基本模式是具有一个布尔状态属性,该属性决定是否应提示它们。 根据是否为任何表单字段选择了值,通过表单更新此状态。 在表单内,您将呈现一个Prompt
组件,并传入两个属性: when
(这是之前设置的布尔状态)和要显示的message
。
Below is an example (it mostly follows the example from ReactTraining prevent transitions):
下面是一个示例(主要遵循ReactTraining prevent transitions的示例):
摘要 (Summary)
In the article, you will have learned all the basics to use React Router in your web applications. You should be even able to converse with your many friends and family about the joys of React Routing.
在本文中,您将学习在Web应用程序中使用React Router的所有基础知识。 您甚至应该能够与您的许多朋友和家人谈论React Routing的乐趣。
If you liked this article, please share your like with a friendly clap.
如果您喜欢这篇文章,请以友好的掌声与您分享。
If you didn’t like this article and would like to register your resentment, you can do so by giving a hateful clap.
如果您不喜欢本文,但想表达您的不满,可以通过令人讨厌的鼓掌来实现。
The opinions expressed in this publication are those of the author. They do not purport to reflect the opinions or views of any organization or business that the author may be connected to.
本出版物中表达的观点为作者的观点 。 它们并非旨在反映作者可能与之联系的任何组织或企业的观点或看法。
翻译自: https://www.freecodecamp.org/news/bluffers-guide-to-react-router-v4-20f607a10478/