All you need to know about using React.js
react-router-dom
package and how to use it (with code and result GIF examples).您需要了解有关使用React.js
react-router-dom
软件包以及如何使用它(带有代码和结果GIF示例)的所有知识。
本文将介绍的内容: (What will be covered in this article:)
- 1. Installing 1.安装
- 2. Creating your first Routes using Switch 2.使用Switch创建您的第一个路线
- 3. Nested Routing 3.嵌套路由
- 4. Prompt component 4.提示组件
- 5. NavLink component 5. NavLink组件
- 6. 404 page (page not found) 6. 404页(找不到页面)
- 7. Getting Route props (match, location, history) 7.获取路线道具(比赛,位置,历史)
- 8. Route Parameters 8.路线参数
- 9. URLSearchParams 9. URLSearchParams
- 10. Redirect component 10.重定向组件
- 10.1. Private routes 10.1。 私人路线
- 10.2. Redirect from an old page to a new one 10.2。 从旧页面重定向到新页面
- 11. Animation 11.动画
- 12. Secure your application 12.保护您的应用程序
I will be using a starter Typescript React.js project that was created using the most popular create-react-app
script. No additional packages (only eslint
and prettier
, but that is for code formatting )
我将使用使用最受欢迎的create-react-app
脚本create-react-app
的入门Typescript React.js项目。 无需额外的软件包( 仅 eslint
和 prettier
,但这是代码格式化 )
npx create-react-app my-app --template typescript
# oryarn create react-app my-app --template typescript
… and I removed all styles. They will only distract us from the main topic.
…我删除了所有样式。 他们只会分散我们的注意力。
1.安装 (1. Installing)
To start using React Router
we need to add it to our dependencies :
要开始使用React Router
我们需要将其添加到我们的依赖项中:
yarn add react-router-dom// Because we are using typescript project
// we need to istall @types/react-router-dom package tooyarn add @types/react-router-dom
And that’s it, we are totally ready!
就是这样,我们已经完全准备好了!
2.使用Switch创建您的第一条路线 (2. Creating your first Routes using Switch)
Before we will use the functionality of React Router
we will need to create first component pages that we will use for showing changes when a User clicks on a Link
:
在使用React Router
的功能之前,我们需要创建第一个组件页面,用于在用户单击Link
时显示更改:
Next, we need to add Navigation and Routes components. (Obviously, we could write all in one Component but in this case, it will be harder to read and understand what is happening)
接下来,我们需要添加导航和路线组件。 ( 显然,我们可以在一个组件中编写所有组件,但是在这种情况下,将很难阅读和理解正在发生的事情 )
Navigation component:
导航组件:
Routes component:
路线部分:
And a final touch… We need to wrap our application with BrowserRouter
component (as Router
):
最后一点……我们需要用BrowserRouter
组件(如Router
)包装应用程序:
In Router version 3 instead of using
BrowserRouter
->HashRouter
was used. When Router version 4 was releasedHashRouter
became deprecated.在路由器版本3中,而不是使用
BrowserRouter
>HashRouter
。 当路由器版本4发布时,HashRouter
被弃用了 。
Let’s test it out:
让我们测试一下:
!!! I want to notice one thing about
Route
— it is not comparing routes in strict mode like “some-string” === “some-other-string”. To solve this issue you need to passexact={true}
property, or to wrap you routes with Switch and place them in right order.!!! 我想注意到有关
Route
一件事-它不是在严格模式下比较路由,例如“ some-string” ===“ some-other-string”。 要解决此问题,您需要传递exact={true}
属性,或使用Switch封装您的路由并将其以正确的顺序放置。
Let’s position our three routes in “wrong” order, like this:
让我们以“错误”的顺序放置我们的三条路线,如下所示:
… then your Routes will not change, even if path is changing:
…那么即使路径改变了,您的路线也不会改变:
Switch
will “get” first route, and Router
will think this way:
Switch
将“获取”第一条路由,而Router
将以这种方式思考:
User want
“/second”
route to be shown;用户希望显示
“/second”
路线;First route’s path is
“/”
;第一路线的路径为
“/”
;Does
“/second”
starts with“/”
— yes;不
“/second”
开始用“/”
-是的;Show
First Page
显示
First Page
To solve this issue, you need to pass exact={true}
prop to Route
, or place routes in the right order in Switch
:
要解决此问题,您需要将exact={true}
属性传递给Route
,或以正确的顺序在Switch
放置路由:
3.嵌套路由 (3. Nested Routing)
With React Router you can nest your routes inside other routes just like any other routes, like this:
使用React Router,您可以像其他路由一样将路由嵌套在其他路由中,如下所示:
!!! In this example, you must be aware of one thing. Do you remember how we added exact={true}
to our previous root routes components?
!!! 在此示例中,您必须意识到一件事。 您是否还记得我们如何在以前的根路由组件中添加exact={true}
?
Because of that, ThirdPage
sub-pages will not be rendered, because the route path "/third/3–1" or “/third/3-2”, etc
will not be the exact match of “/third”
.
因此,将不会呈现ThirdPage
子页面,因为路由路径为" /third/3–1" or “/third/3-2”, etc
ThirdPage
" /third/3–1" or “/third/3-2”, etc
不会与“/third”
完全匹配。
In this case, React Router
will render “nothing”.
在这种情况下, React Router
将呈现“ 无 ”。
6. 404页(找不到页面) (6. 404 page (page not found))
It is not the best practice to show “nothing” to a User if the route is not found. For this case we will add a new component “PageNotFound”:
如果找不到路由,最好的做法是不向用户显示“无”。 对于这种情况,我们将添加一个新组件“ PageNotFound”:
And after that, we will need to add it to our Switch Routes without specifying path
prop.
然后,我们需要将其添加到我们的交换路由中,而无需指定path
属性。
Route with no path specified is equivalent to:
<Route path="*">
...
Route>
Let’s see how it will look like in our app:
让我们看看它在我们的应用程序中的样子:
7.获取路线道具(比赛,位置,历史) (7. Getting Route props (match, location, history))
There are thee main routing props:
有主要的路由道具 :
- match 比赛
- location 位置
- history 历史
What are four main approaches to get them?
获得它们的四种主要方法是什么?
If you will pass your component to
Route
as acomponent
prop:如果要将组件作为
component
属性传递给Route
:
<Route path="/" exact={true} component={FirstPage} />
2. If you will pass your component to Route
as a render
prop:
2.如果将组件作为render
道具传递给Route
:
<Route
path="/"
exact={true}
render={(props) => {
return <FirstPage {...props} />;
}}
/>
3. If you will wrap your component using withRouter
:
3.如果要使用withRouter
包装组件:
Our routes:
我们的路线:
And our FirstPage
component:
还有我们的FirstPage
组件:
4. Use hooks useHistory
, useLocation
, useRouteMatch
4.使用钩子useHistory
, useLocation
, useRouteMatch
8.路线参数 (8. Route Parameters)
What if you we want to show a list of items on a “/items”
path and a specific item on a “/items/:itemId”
path:
如果我们要在“/items”
路径上显示项目列表,而在“/items/:itemId”
路径上显示特定项目,该怎么办:
This is where match
props will be useful. As you remember we can get match props using 4 different ways, and I will be using the first one.
这是match
道具会有用的地方。 您还记得我们可以使用4种不同的方式来获得比赛道具,而我将使用第一种。
<Route path="/items" component={Items} exact={true} />
<Route path="/items/:userId" component={Item} exact={true} />
Items component:
项目组成:
As you can see here that we are using
history
to redirect User to the“/users/:userId”
page when he clicks on a row;如您所见,当
“/users/:userId”
单击一行时,我们正在使用history
将用户重定向到“/users/:userId”
页面;And we are using
location.pathname
to show User’s current path, just for a demonstration我们使用
location.pathname
来显示用户的当前路径,仅用于演示
Item component:
项目组成:
The main difference in an Item component is that we are redirecting User back using
history.goBack()
function;Item组件的主要区别是我们使用
history. goBack()
将用户重定向回history. goBack()
history. goBack()
函数;
Row and Column components that are just a simple divs. And users — array of simple objects.
行和列组件只是一个简单的div。 和用户 -简单对象数组。
9. URLSearchParams (9. URLSearchParams)
What if you want to add some search params like: order/sort
, filter
, exclude
, page
etc.
如果您想添加一些搜索参数,例如: order/sort
, filter
, exclude
, page
等,该怎么办?
It will be not very nice to use match.params
because your Route path will look really weird and you will need to match the order each time you redirect to this page:
使用match.params
并不是很好,因为您的Route路径看起来确实很奇怪,并且每次重定向到此页面时都需要匹配顺序:
path='/items/:itemId/:sort/:filter/:exclude/:page/...'
In this case, URLSearchParams
will come in handy.
在这种情况下, URLSearchParams
上用场。
Let’s take a look at how sort
and order
search params could work together:
让我们看一下sort
和order
搜索参数如何协同工作:
I have updated Items component with implemented sort
and order
search params handlers:
我已经更新了Items组件,并实现了sort
和order
搜索参数处理程序:
10.重定向组件 (10. Redirect component)
10.1私人路线 (10.1 Private routes)
What if User is trying to get a Route to which he doesn’t has access? This is where Redirect
component can be in handy:
如果用户尝试获取他无权访问的路由怎么办? 这是Redirect
组件可以派上用场的地方:
Private page:
私人页面:
Routes:
路线:
Each time user will try to get content of a Private
page -> he will be redirected to the root page.
每次用户尝试获取Private
页面的内容->他将被重定向到根页面。
Another popular approach for redirecting is to use
history.push()
method. It will do exactly the same as Redirect.另一种流行的重定向方法是使用
history.push()
方法。 它将与重定向完全相同。Example:
例:
import { useHistory } from 'react-router-dom';... component ...const history = useHistory();history.push('/third');
10.2从旧页面重定向到新页面 (10.2 Redirect from old to new page)
What if you got an old link or a route that you app been using years ago, and now you’ve created a new awesome page that should be visible to the user, but you want to show his new page by the old route, simple:
如果您有一个旧链接或您的应用程序在几年前一直在使用的路线,现在又创建了一个新的页面,该页面应该对用户可见,但是您希望通过旧的路线来显示他的新页面,该怎么办呢? :
This is it! Now, if a User will try to reach ‘/oldPage’
he will be automatically redirected to the new one.
就是这个! 现在,如果用户尝试访问'/oldPage'
他将被自动重定向到新的页面。
11.动画 (11. Animation)
What if we would like our routes to change in a smooth way. How can we do that?
如果我们希望我们的路线能够平稳地改变,该怎么办? 我们该怎么做?
First, we would need to install react-transition-group package:
首先,我们需要安装react-transition-group软件包:
npm install
// oryarn add
if you are using TS project you will need @types/react-transition-group
too.
如果您正在使用TS项目,则也将需要@types/react-transition-group
。
After that, you can wrap your
component with TransitionGroup
component:
之后,可以用TransitionGroup
组件包装
组件:
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import './styles.css';<TransitionGroup>
<CSSTransition
key={}
classNames={'anim'}
timeout={1000}>
<Switch>
...
Switch>
CSSTransition>
TransitionGroup>
and add simple CSS styles:
并添加简单的CSS样式:
.anim-enter {
opacity: 0;
z-index: 1;}.anim-exit {
display: none;}.anim-enter.anim-enter-active {
opacity: 1;
transition: opacity 1s ease-in;}
12.保护您的应用程序 (12. Secure your application)
This example is not about
React Router
only, it’s more about usingReact Routes
in combination with other features, that React provides. We will be usingRedirect
,useLocation
,useContext
,useEffect
,useState
, andlocalStorage
.这个例子不仅涉及
React Router
,还涉及将React Routes
与React提供的其他功能结合使用。 我们将使用Redirect
,useLocation
,useContext
,useEffect
,useState
和localStorage
。
Previous example is nice and simple, but what if we want to secure all our routes, not only the PrivatePage
. And what if user logged-in, closed the application, and returned after some time and want to open “/third”
page. Login again? Let’s see one of the approaches, how we can solve this.
前面的示例很简单,但是如果我们想保护所有路由,而不仅是PrivatePage
,该怎么办? 如果用户登录,关闭应用程序并在一段时间后返回并想要打开“/third”
页面,该怎么办。 重新登录? 让我们看看其中一种方法,我们如何解决这个问题。
First, let's create a context:
首先,让我们创建一个上下文:
Next, we need to add AuthHandler
component:
接下来,我们需要添加AuthHandler
组件:
And AuthValidation
component:
和AuthValidation
组件:
Wrap our App
component with AuthHandler
:
用AuthHandler
包装我们的App
组件:
After that, we need to modify our LoginPage
component:
之后,我们需要修改我们的LoginPage
组件:
And add LogOut
component:
并添加LogOut
组件:
Add final modification, we need to add Logout link to our Navigation component:
添加最终修改,我们需要将注销链接添加到导航组件:
<li>
<NavLink to="/logout" activeStyle={{ color: 'green' }} exact={true}>
Logout page
NavLink>
li>
让我们测试一下: (Let’s test it out:)
Login/Logout result:
登录/注销结果:
Login/Exit application example:
登录/退出应用程序示例:
If I forgot to describe some valuable features, or if you got some questions — I will be glad to answer. Happy codding!
如果我忘记描述一些有价值的功能,或者您有任何疑问,我将很乐意回答。 祝大家高兴!
翻译自: https://medium.com/swlh/react-js-router-in-examples-93c778a37888