如何升级到React Router 4

Not long after I started working at my current position, the team realized that it would be necessary for us to upgrade to React 16 so we could use a new UI library we were keen on adopting.

在我开始担任现任职务后不久,团队意识到需要升级到React 16,以便我们可以使用渴望采用的新UI库。

To figure out how much time this upgrade would require, we looked at all of our current packages to see if they were compatible with React 16, and to see if we were still using unsupported or deprecated packages.

为了弄清楚这次升级需要多少时间,我们查看了所有当前的软件包以查看它们是否与React 16兼容,并查看我们是否仍在使用不受支持或不推荐使用的软件包。

The beginnings of our code base had been built by developers who used whatever open source or third party library they wanted, without actually vetting them. Thus, we found that a lot of the packages were deprecated and needed to be replaced ASAP.

我们的代码库的开始是由开发人员构建的,他们使用了他们想要的任何开源或第三方库,而没有实际对其进行审核。 因此,我们发现许多软件包已被弃用,需要尽快替换。

One of the biggest surprises for us was the deprecation of react-router-redux. We were using react-router-redux in conjunction with react-router v3. This led us to think critically about why we were using redux in our router in the first place.

对我们来说,最大的惊喜之一就是对react-router-redux的弃用。 我们将react-router-redux与react-router v3结合使用。 这使我们开始认真思考为什么我们首先要在路由器中使用redux

Once we started to look into react router v4, we realized that the new features would pretty much eliminate any reason for us to use an additional library to connect our router and redux. So, that left us in the position to just upgrade from react router 3 to 4, and remove  react-router-redux from our application.

一旦开始研究React Router v4,我们意识到新功能几乎消除了我们使用附加库来连接路由器和redux任何理由。 因此,这使我们只能从React Router 3升级到4,并从应用程序中删除react-router-redux

So, I was tasked with upgrading our router to v4 after only being in the position and working with React for about 2 months. This was because upgrading from React Router 3 to React Router 4 sounded like it should be a trivial undertaking. But, as I quickly found out, it was a little bit more involved than I anticipated.

因此,我仅在担任职务并与React一起工作了大约2个月后,便将路由器升级到v4。 这是因为从React Router 3升级到React Router 4听起来像是一件微不足道的事情。 但是,正如我很快发现的那样,它的参与程度超出了我的预期。

Looking through the documentation, the GitHub repo, and many, many Stack Overflow answers, I finally pieced together the steps for the upgrade and wanted to share my findings — especially to explain how and why certain changes are made.

通过查阅文档GitHub存储库以及许多很多Stack Overflow答案,我终于拼凑出了升级步骤,并希望分享我的发现,尤其是解释如何以及为何进行某些更改。

The biggest change to note, from the creators of React Router, is that the upgrade from React Router 3 to React Router 4 is more than just updating a few libraries and features — it allows you to fundamentally change how your Router works. The creators of React Router wanted to go back to a simple Router, allowing the developer to customize it however they would like.

从React Router的创建者那里注意到的最大变化是,从React Router 3升级到React Router 4不仅仅是升级一些库和功能-它使您可以从根本上改变Router的工作方式。 React Router的创建者想要回到一个简单的Router,允许开发人员根据自己的喜好对其进行自定义。

I’ve split up this guide into 5 different parts:

我将本指南分为5个不同的部分:

  1. Package

  2. History

    历史
  3. Route

    路线
  4. Props

    道具
  5. Redux Integration

    Redux整合


(Package)

React  Router v4 package structure changed such that it’s no longer necessary  to install react-router — you have to install react-router-dom (and  uninstall react-router), but you don’t lose anything since it re-exports  all of react-router’s exports. This means you also have to update any  react-router import statements to react-router-dom.

React Router v4包的结构已更改,因此不再需要安装react-router -您必须安装react-router-dom (并卸载react-router ),但是您不会丢失任何东西,因为它会重新导出所有的react-router的出口。 这意味着您还必须将所有react-router导入语句更新为react-router-dom



历史 (History)

History is an essential part of routing, allowing us to remember where we came from and where we are currently. History comes in many forms for react-router, and could take a while to explain. So, to keep this article on topic, I’ll simply recommend that you read through this article that explains history in relation to react router 4. This article should cover most cases of your usage of history.

历史是路由的重要组成部分,它使我们能够记住自己来自何方以及当前所处的位置。 React路由器的历史形式很多,可能需要一段时间才能解释。 因此,为了使本文保持话题性,我只建议您通读这篇文章 ,以解释与React Router 4相关的历史记录。本文应涵盖大多数使用历史记录的情况。



路线 (Route)

React Router v3 allowed us to place all of our application routes in one file, which we’ll call router.js. However, React Router v4 allows you to  place Routes in the components that they’re rendering. The idea here is to dynamically route the application — in other words, the routing takes place as the app is rendering.

React Router v3允许我们将所有应用程序路由放在一个文件中,我们将其称为router.js。 但是,React Router v4允许您将Routes放置在它们正在渲染的组件中。 这里的想法是动态地路由应用程序-换句话说,路由是在应用程序呈现时进行的。

However,  if you have a decent-size legacy code base you’re working with, you probably won’t be making a change that big. Luckily, React Router v4  still allows you to place all the routes in a central file, which is how I’ll create all of our examples. There are, however, a few older components and features that will need replacing.

但是,如果您使用的是相当大的遗留代码库,则可能不会进行太大的更改。 幸运的是,React Router v4仍然允许您将所有路由放置在一个中央文件中,这就是我将创建所有示例的方式。 但是,有一些较旧的组件和功能需要替换。

索引路由 (IndexRoute)

Previously,  IndexRoute was used as a route for some default UI of a parent Route. But, in v4, IndexRoute is no longer used, since this functionality is  now available in Route.

以前, IndexRoute用作父Route的某些默认UI的路由。 但是,在v4中,不再使用IndexRoute ,因为该功能现在在Route中可用。

For providing default UI, multiple Routes that have the same path will let all of the associated components render:

为了提供默认的UI,具有相同路径的多个Route将使所有关联的组件呈现:

import { BrowserRouter as Router, Route } from 'react-router-dom';

<Router>
    // example of our route components
    <Route path="/" component={Home} />
    <Route path="/" component={About} />
    <Route path="/" component={Contact} />
</Router>

So, all of the Components — Home, About, and Contact — will render. Because of this, you can no longer nest Routes, either.

因此,所有组件(“ Home ,“ About ”和“ Contact )都将呈现。 因此,您也不能再嵌套路由。

Additionally, to allow for better matching without the use of IndexRoute, you can use the exact keyword.

另外,为了在不使用IndexRoute情况下实现更好的匹配,可以使用完全匹配的关键字。

import { BrowserRouter as Router, Route } from 'react-router-dom';

<Router>
    // example of our route components
    <Route exact path="/" component={Home} />
    <Route path="/about" component={About} />
</Router>

独家路由 (Exclusive Routing)

After adding in the exact keyword, “something.com/about” will be routed to  when the router sees a path “/about”. But now what if you have another  path, “/about/team”? As I stated before, the router will render anything  that matches. So, the components associated with both “/about” and  “/about/team” will render. If that’s what you intended, then that’s great! However, if this isn’t what you want, you may have to put a  Switch around this group of Routes. This will allow the first path that  matches the URL to render.

在添加了确切的关键字之后,当路由器看到路径“/about”时, “something.com/about”将被路由到。 但是现在,如果您有另一条路径“/about/team”怎么办? 如前所述,路由器将呈现任何匹配的内容。 因此,与“/about”“/about/team”相关联的组件将呈现。 如果这就是您的意图,那就太好了! 但是,如果这不是您想要的,则可能必须在这组路由周围放置一个交换机。 这将允许渲染与URL匹配的第一个路径。

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

<Router>
    <Switch>
       <Route exact path ="/" component={Home} />
       <Route path="/about/team" component={Team} />
       <Route path="/about" component={About} />
    </Switch>
</Router>

Note  that the keyword exact still has to appear for the Home component —  otherwise it would match for the subsequent routes. Also note that we  have to list “/about/team” before “/about” so the route goes to the Team component instead of the About component when it sees  “something.com/about/team”. If it saw “/about” first, it would stop  there and render the About component because Switch only renders the  first component that matches.

请注意,仍然必须为Home组件显示关键字“精确”-否则它将与后续路由匹配。 还要注意的是,我们必须名单“/about/team”“/about”这样的途径进入到Team组成,而不是About组件时,看到“something.com/about/team” 。 如果它首先看到“/about” ,它将停在那里并呈现About组件,因为Switch只呈现匹配的第一个组件。

默认路线 (Default Route)

A default route, or a “catch all” route, commonly used for 404 pages, is the route you use when none of the routes match.

默认路由或“全部捕获”路由(通常用于404页)是在没有路由匹配时使用的路由。

In React Router v3, a default Route was:

在React Router v3中,默认Route为:

<Route path=”*” component={NotFound} />

<Route path=”*” component={NotFound} />

In React Router v4, the default Route was changed to:

在React Router v4中,默认Route更改为:

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

<Router>
    <Switch>
       <Route exact path ="/" component={Home} />
       <Route path="/about/team" component={Team} />
       <Route path="/about" component={About} />
       <Route component={NotFound} /> // this is our default route
    </Switch>
</Router>

When  you don’t include a path in a Route, the component will always render.  So, as we discussed above, we can use Switch to get only one component  to render, and then place the “catch all” route very last (so it doesn’t  use that one before the Router gets a chance to check the rest of the  paths), so something will always render even if the other paths don’t  match.

当您不在Route包括路径时,组件将始终呈现。 因此,如上所述,我们可以使用Switch仅获取一个要渲染的组件,然后将“全部捕获”路由放置在最后(因此,在Router有机会检查其余部分之前,它不使用该组件)路径),因此即使其他路径不匹配,也会始终呈现某些内容。

onEnter (onEnter)

Previously,  you could use onEnter to make sure the component of the Route has all  of the information it needs or as a check (such as to make sure the user  is authenticated) before the component rendered.

以前,您可以使用onEnter来确保Route的组件具有其所需的所有信息,或者作为呈现组件之前的检查(例如,确保用户通过身份验证)。

This  feature has been deprecated because the new structure of Routes is that  they should act like components, so you should take advantage of component lifecycle methods instead.

不推荐使用此功能,因为Routes的新结构是它们应该像组件一样工作,因此您应该改用组件生命周期方法。

In React Router v3:

在React Router v3中:

<Route path=”/about” onEnter={fetchedInfo} component={Team}/>

<Route path=”/about” onEnter={fetchedInfo} component={Team}/>

Becomes:

成为:



道具 (Props)

In  React Router v4, the props passed through the router have changed, as  did the way they are accessed. The Route now passes three props:

在React Router v4中,通过路由器的道具已经更改,访问方式也发生了变化。 路线现在通过三个道具:

  • history

    history

  • location

    location

  • match

    match

历史 (history)

history contains a lot of other properties and methods, so I won’t list all of  them, but here is a selection that might be most commonly used:

history包含许多其他属性和方法,因此我不会列出所有这些属性和方法,但以下是最常用的选择:

  • length: number of entries in the history stack

    length :历史记录堆栈中的条目数

  • location: contains the same information as below

    location :包含以下相同信息

  • push(path, [state]): pushes new entry on history stack

    push(path, [state]) :将新条目推入历史记录堆栈

  • goBack(): allows you to move the pointer on the history stack back 1 entry

    goBack() :允许您将历史记录堆栈上的指针移回1项

It’s  important to note that history is mutable, and while it contains a location property, this instance of location shouldn’t be used since it  could have been changed. Instead, you want to use the actual location prop discussed below.

重要的是要注意, history是可变的,虽然它包含location属性,但是不应使用此location实例,因为它可能已更改。 相反,您想使用下面讨论的实际location道具。

位置 (location)

The location has properties:

该位置具有以下属性:

  • pathname

    pathname

  • search

    search

  • hash

    hash

  • state

    state

location.search is used to replace location.query and it must be parsed. I used  URLSearchParams to parse it. So a URL such as  “https://something.com/about?string=’hello’” would be parsed as such:

location.search用于替换location.query ,必须对其进行解析。 我用URLSearchParams来解析它。 因此,诸如“https://something.com/about?string='hello'”类的URL将被解析为:

Additionally,  the state property can be used to pass the location-specific state of components through props. So, if you wanted to pass some information  from one component to another, you could use it like this:

另外, state属性可用于通过prop传递组件的location特定state 。 因此,如果您想将某些信息从一个组件传递到另一个组件,则可以像这样使用它:

...
// To link to another component, we could do this:
<Link to='/path/' />

// However, if we wanted to add state to the location, we could do this:
const location = {
    pathname: '/path/',
    state: { fromDashboard: true },
}
<Link to={location} />
...

So, once we get to the component rendered by that path, we’ll have access to fromDashboard from location.state.fromDashboard.

因此,一旦到达该路径渲染的组件,就可以从location.state.fromDashboard访问fromDashboard

比赛 (match)

match has the following properties:

match具有以下属性:

  • params:  gets the dynamic segments of the path from the URL — for example if the  path is “/about/:id”, in the component, accessing  this.props.match.params will give you the id in the URL

    params :从URL获取路径的动态段-例如,如果路径为“/about/:id” ,则在组件中,访问this.props.match.params将为您提供URL中的ID

  • isExact: true if the entire URL was matched

    isExact :如果整个URL都匹配, isExact true

  • path: the path in the routes that was matched

    path :匹配的路线中的路径

  • url: the matched portion of the URL

    urlurl的匹配部分

Redux整合 (Redux Integration)

As  I addressed earlier, we found that in our case, we didn’t need to have an additional library to connect redux with our router, especially since our main use case for this — Blocked Updates — was covered by react  router.

正如我之前提到的,我们发现在我们的案例中,我们不需要额外的库来将redux与我们的路由器连接,特别是因为我们的主要用例(阻止更新)已被react路由器覆盖。

阻止的更新 (Blocked Updates)

In  some cases, the app doesn’t update when the location changes. This is called a “Blocked Update”. This can happen if both of these conditions  are met:

在某些情况下,位置更改时应用不会更新。 这称为“阻止更新”。 如果同时满足以下两个条件,则可能发生这种情况:

  1. The component is connected to Redux via connect()(Component).

    该组件通过connect()(Component)连接到Redux。

  2. The component isn’t rendered by a <Route>

    该组件不是由<Route>呈现的

In these cases, I wrapped the component’s connect with withRouter.

在这些情况下,我用withRouter包装了组件的连接。

This  allowed the router information to follow the component when it gets linked to, so the app still updates when the Redux state changes.

这允许路由器信息在链接到组件时跟随组件,因此当Redux状态更改时,应用程序仍会更新。



And that’s it!

就是这样!

This upgrade took me over a week — a few days of trying to figure out how to do it at all, and then another few days to start actually making changes. Upgrading to React Router 4 is a huge change not to be taken lightly, but it’ll make your router a lot more lightweight and easy to use.

这次升级花了我一个多星期的时间-几天试图弄清楚该怎么做,然后又花了几天才开始实际进行更改。 升级到React Router 4是一个巨大的变化,不要轻描淡写,但是它将使您的路由器更加轻巧和易于使用。

Please don’t hesitate to comment/ask questions!

请不要犹豫,评论/提问!

翻译自: https://www.freecodecamp.org/news/a-guide-to-upgrading-to-react-router-4/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值