Sådan opgraderes til React Router 4

Ikke længe efter at jeg begyndte at arbejde på min nuværende stilling, indså teamet, at det ville være nødvendigt for os at opgradere til React 16, så vi kunne bruge et nyt UI-bibliotek, som vi var interesserede i at vedtage.

For at finde ud af, hvor meget tid denne opgradering ville kræve, så vi på alle vores nuværende pakker for at se, om de var kompatible med React 16, og for at se, om vi stadig brugte ikke-understøttede eller forældede pakker.

Begyndelsen af ​​vores kodebase var bygget af udviklere, der brugte det open source- eller tredjepartsbibliotek, de ønskede, uden faktisk at undersøge dem. Således fandt vi ud af, at mange af pakkerne var udfaset og skulle udskiftes ASAP.

En af de største overraskelser for os var afskrivningen af react-router-redux. Vi brugte react-router-reduxsammen med react-router v3. Dette fik os til at tænke kritisk over, hvorfor vi reduxi første omgang brugte i vores router.

Når vi begyndte at undersøge reagerer router v4, indså vi, at de nye funktioner stort set ville eliminere enhver grund for os til at bruge et ekstra bibliotek til at forbinde vores router og redux. Så det efterlod os i stand til bare at opgradere fra reagere router 3 til 4 og fjerne   react-router-reduxfra vores applikation.

Så jeg fik til opgave at opgradere vores router til v4 efter kun at have været i positionen og arbejdet med React i cirka 2 måneder. Dette var fordi opgradering fra React Router 3 til React Router 4 lød som om det skulle være en triviel opgave. Men som jeg hurtigt fandt ud af, var det lidt mere involveret, end jeg forventede.

Når jeg gennemgik dokumentationen, GitHub-repoen og mange, mange Stack Overflow-svar, samlede jeg endelig trinene til opgraderingen og ønskede at dele mine fund - især for at forklare, hvordan og hvorfor visse ændringer foretages.

Den største ændring at bemærke fra skaberne af React Router er, at opgraderingen fra React Router 3 til React Router 4 er mere end bare at opdatere et par biblioteker og funktioner - det giver dig mulighed for fundamentalt at ændre, hvordan din Router fungerer. Skaberne af React Router ønskede at gå tilbage til en simpel Router, der tillader udvikleren at tilpasse den, uanset hvordan de vil.

Jeg har opdelt denne vejledning i 5 forskellige dele:

  1. Pakke
  2. Historie
  3. Rute
  4. Rekvisitter
  5. Redux-integration

Pakke

React Router v4 pakkestruktur ændret således, at det ikke længere er nødvendigt at installere react-router - du er nødt til at installere react-router-dom(og afinstallere react-router), men du mister ikke noget, da det reeksporterer al react-routereksport. Dette betyder, at du også skal opdatere eventuelle   react-routerimportopgørelser til react-router-dom.

Historie

Historie er en vigtig del af rutingen, så vi kan huske, hvor vi kom fra, og hvor vi er i øjeblikket. Historie findes i mange former for reagerer-router og kan tage et stykke tid at forklare. Så for at holde denne artikel om emnet, vil jeg ganske enkelt anbefale, at du læser igennem denne artikel, der forklarer historik i forhold til reagerer router 4. Denne artikel skal dække de fleste tilfælde af din brug af historie.

Rute

React Router v3 tillod os at placere alle vores applikationsruter i en fil, som vi kalder router.js. Imidlertid giver React Router v4 dig mulighed for at placere Routes i de komponenter, de gengiver. Ideen her er at dynamisk rute applikationen - med andre ord finder routingen sted, når appen gengives.

Men hvis du har en anstændig størrelse ældre kodebase, du arbejder med, vil du sandsynligvis ikke foretage en ændring så stor. Heldigvis giver React Router v4 dig stadig mulighed for at placere alle ruterne i en central fil, sådan opretter jeg alle vores eksempler. Der er dog et par ældre komponenter og funktioner, der skal udskiftes.

IndexRoute

Tidligere   IndexRouteblev brugt som en rute til nogle standardgrænseflader for en overordnet rute. Men i v4 IndexRoutebruges den ikke længere, da denne funktionalitet nu er tilgængelig i Route.

For at levere standard-brugergrænsefladen vil flere ruter, der har den samme sti, lade alle de tilknyttede komponenter gengive:

import { BrowserRouter as Router, Route } from 'react-router-dom';  // example of our route components    

Så alle komponenterne - Home, Aboutog Contact- vil gøre. På grund af dette kan du heller ikke længere rede ruter.

Derudover IndexRoutekan du bruge det nøjagtige nøgleord for at give mulighed for bedre matchning uden brug af .

import { BrowserRouter as Router, Route } from 'react-router-dom';  // example of our route components   

Eksklusiv routing

Efter tilføjelse af det nøjagtige nøgleord “something.com/about”vil blive dirigeret til når routeren ser en sti “/about”. Men hvad nu hvis du har en anden vej “/about/team”? Som jeg nævnte før, vil routeren gengive alt, der matcher. Så komponenterne er forbundet med både “/about”og   “/about/team”vil gøre. Hvis det var hvad du havde til hensigt, så er det godt! Men hvis dette ikke er, hvad du vil, skal du muligvis sætte en switch omkring denne gruppe af ruter. Dette gør det muligt at gengive den første sti, der matcher URL'en.

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

Bemærk, at nøgleordet nøjagtigt stadig skal vises for Home-komponenten - ellers svarer det til de efterfølgende ruter. Bemærk også, at vi skal liste “/about/team”før, “/about”så ruten går til Teamkomponenten i stedet for Aboutkomponenten, når den ser   “something.com/about/team”. Hvis det så “/about”først, ville det stoppe der og gengive Aboutkomponenten, fordi Switch kun gengiver den første komponent, der matcher.

Standardrute

En standardrute eller en "fang alle" -rute, der almindeligvis bruges til 404 sider, er den rute, du bruger, når ingen af ​​ruterne matcher.

I React Router v3 var en standard Route:

I React Router v4 blev standard Routeændret til:

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';       // this is our default route  

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.

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.

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.

In React Router v3:

Becomes:

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';        
... componentDidMount() { this.props.fetchInfo(); } ...

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:

  • history
  • location
  • 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:

  • length: number of entries in the history stack
  • location: contains the same information as below
  • push(path, [state]): pushes new entry on history stack
  • goBack(): allows you to move the pointer on the history stack back 1 entry

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.

location

The location has properties:

  • pathname
  • search
  • hash
  • 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  “//something.com/about?string=’hello’” would be parsed as such:

... const query = new URLSearchParams(this.props.location.search) const string = query.get('string') // string = 'hello' ...

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:

... // To link to another component, we could do this:  // However, if we wanted to add state to the location, we could do this: const location = { pathname: '/path/', state: { fromDashboard: true }, }  ...

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

match

match has the following properties:

  • 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
  • isExact: true if the entire URL was matched
  • path: the path in the routes that was matched
  • url: the matched portion of the URL

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.

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).
  2. The component isn’t rendered by a

In these cases, I wrapped the component’s connect with 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.

And that’s it!

Denne opgradering tog mig over en uge - et par dage med at forsøge at finde ud af, hvordan jeg overhovedet gør det, og derefter endnu et par dage til at begynde med at foretage ændringer. Opgradering til React Router 4 er en enorm ændring, der ikke skal tages let, men det gør din router meget mere let og nem at bruge.

Tøv ikke med at kommentere / stille spørgsmål!