Cum sa faceti upgrade la React Router 4

Nu după mult timp după ce am început să lucrez la poziția mea actuală, echipa și-a dat seama că ar fi necesar să facem upgrade la React 16, astfel încât să putem folosi o nouă bibliotecă UI pe care am fost dornici să o adoptăm.

Pentru a afla cât timp ar necesita acest upgrade, am analizat toate pachetele noastre actuale pentru a vedea dacă acestea sunt compatibile cu React 16 și pentru a vedea dacă folosim în continuare pachete neacceptate sau depreciate.

Începuturile bazei noastre de coduri au fost construite de dezvoltatori care au folosit orice sursă deschisă sau bibliotecă terță parte doreau, fără a le verifica. Astfel, am constatat că multe dintre pachete erau învechite și trebuiau înlocuite cât mai curând posibil.

Una dintre cele mai mari surprize pentru noi a fost deprecierea react-router-redux. Foloseam react-router-redux împreună cu react-router v3. Acest lucru ne-a determinat să ne gândim critic la motivele pentru care foloseam redux pe routerul nostru, în primul rând.

Odată ce am început să analizăm react router v4, ne-am dat seama că noile funcții vor elimina aproape orice motiv pentru care să folosim o bibliotecă suplimentară pentru a ne conecta routerul și redux. Deci, asta ne-a lăsat în poziția de a face upgrade doar de la react router 3 la 4 și de a elimina react-router-redux din aplicația noastră.

Deci, am fost însărcinat să fac upgrade la routerul nostru la v4 după ce am fost în poziție și am lucrat cu React timp de aproximativ 2 luni. Acest lucru se datorează faptului că actualizarea de la React Router 3 la React Router 4 suna ca și cum ar trebui să fie o întreprindere banală. Dar, după cum am aflat repede, a fost puțin mai implicat decât am anticipat.

Privind prin documentație, Repo GitHub, și multe, multe răspunsuri Stack Overflow, am pus în cele din urmă pașii pentru actualizare și am vrut să împărtășesc constatările mele – mai ales pentru a explica cum și de ce se fac anumite modificări.

Cea mai mare schimbare de remarcat, de la creatorii React Router, este că actualizarea de la React Router 3 la React Router 4 este mai mult decât actualizarea câtorva biblioteci și caracteristici – vă permite să schimbați în mod fundamental modul în care funcționează routerul. Creatorii React Router au dorit să se întoarcă la un Router simplu, permițând dezvoltatorului să-l personalizeze cum ar dori.

Am împărțit acest ghid în 5 părți diferite:

  1. Pachet
  2. Istorie
  3. Traseu
  4. Recuzită
  5. Integrare Redux

Pachet

Structura pachetului React Router v4 s-a schimbat astfel încât nu mai este necesar să instalați react-router – trebuie să instalați react-router-dom (și dezinstalați react-router), dar nu pierdeți nimic din moment ce reexportează toate react-routerexporturile. Aceasta înseamnă că trebuie să actualizați oricare react-router declarații de import în react-router-dom.


Istorie

Istoria este o parte esențială a rutei, permițându-ne să ne amintim de unde am venit și unde ne aflăm în prezent. Istoria vine în mai multe forme pentru react-router și ar putea dura ceva timp pentru a explica. Deci, pentru a păstra acest articol pe subiect, vă recomand pur și simplu să citiți Acest articol care explică istoricul în legătură cu reacția routerului 4. Acest articol ar trebui să acopere majoritatea cazurilor de utilizare a istoriei.


Traseu

React Router v3 ne-a permis să plasăm toate rutele aplicației noastre într-un singur fișier, pe care îl vom numi router.js. Cu toate acestea, React Router v4 vă permite să plasați Rute în componentele pe care le redă. Ideea aici este să traseu dinamic aplicația – cu alte cuvinte, rutare are loc pe măsură ce aplicația este redată.

Cu toate acestea, dacă aveți o bază de cod moștenită decentă cu care lucrați, probabil că nu veți face o schimbare atât de mare. Din fericire, React Router v4 vă permite în continuare să plasați toate rutele într-un fișier central, așa cum voi crea toate exemplele noastre. Cu toate acestea, există câteva componente și caracteristici mai vechi care vor trebui înlocuite.

IndexRoute

Anterior, IndexRoute a fost folosit ca o rută pentru o anumită interfață de utilizare implicită a unei rute părinte. Dar, în v4, IndexRoute nu mai este utilizat, deoarece această funcționalitate este acum disponibilă în Route.

Pentru furnizarea UI implicită, mai multe rute care au aceeași cale vor permite redarea tuturor componentelor asociate:

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>

Deci, toate componentele – Home, About, și Contact – va reda. Din această cauză, nu mai poți cuibări traseele.

În plus, pentru a permite o potrivire mai bună fără utilizarea IndexRoute, puteți utiliza cuvântul cheie exact.

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>

Rutare exclusivă

După adăugarea cuvântului cheie exact, “something.com/about” va fi direcționat către atunci când routerul vede o cale “/about”. Dar acum dacă ai o altă cale, “/about/team”? După cum am menționat anterior, routerul va reda orice se potrivește. Deci, componentele asociate ambelor “/about” și “/about/team” va reda. Dacă asta ți-ai propus, atunci este minunat! Cu toate acestea, dacă nu doriți acest lucru, poate fi necesar să puneți un comutator în jurul acestui grup de rute. Aceasta va permite redarea primei căi care se potrivește cu adresa 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>

Rețineți că exact trebuie să apară cuvântul cheie pentru componenta Acasă – altfel s-ar potrivi pentru rutele ulterioare. De asemenea, rețineți că trebuie să listăm “/about/team” inainte de “/about” deci traseul merge spre Team componentă în loc de About componentă când vede “something.com/about/team”. Dacă a văzut “/about” mai întâi, s-ar opri aici și ar reda About componentă deoarece Switch redă doar prima componentă care se potrivește.

Ruta implicită

Un traseu implicit sau un traseu „capturați totul”, utilizat în mod obișnuit pentru 404 de pagini, este ruta pe care o utilizați atunci când niciuna dintre rute nu se potrivește.

În React Router v3, o valoare implicită Route a fost:

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

În React Router v4, implicit Route a fost schimbat în:

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>

Când nu includeți o cale într-un Route, componenta va fi întotdeauna redată. Deci, așa cum am discutat mai sus, putem folosi Switch pentru a obține o singură componentă de redat, apoi plasați traseul „catch all” pentru ultima dată (deci nu îl folosește înainte de Router primește șansa de a verifica restul căilor), așa că ceva se va reda întotdeauna chiar dacă celelalte căi nu se potrivesc.

onEnter

Anterior, puteai folosi onEnter pentru a vă asigura că componenta Route are toate informațiile de care are nevoie sau ca o verificare (cum ar fi pentru a vă asigura că utilizatorul este autentificat) înainte de redarea componentei.

Această caracteristică a fost depreciată deoarece noua structură a rutelor constă în faptul că acestea ar trebui să acționeze ca niște componente, deci ar trebui să profitați de metodele ciclului de viață ale componentelor.

În React Router v3:

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

Devine:

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} />
    </Switch>
</Router>
router.js
...

componentDidMount() {
    this.props.fetchInfo();
}

...
Team.js

Recuzită

În React Router v4, accesoriile trecute prin router s-au schimbat, la fel ca și modul în care sunt accesate. Traseul trece acum de trei recuzite:

  • history
  • location
  • match

istorie

history conține o mulțime de alte proprietăți și metode, așa că nu le voi lista pe toate, dar iată o selecție care ar putea fi cea mai frecvent utilizată:

  • length: numărul de intrări în stiva istoric
  • location: conține aceleași informații ca mai jos
  • push(path, [state]): împinge o nouă intrare în stiva de istorie
  • goBack(): vă permite să mutați indicatorul pe stiva istoric 1 intrare

Este important să rețineți că history este modificabil și, în timp ce conține un location proprietate, această instanță a location nu ar trebui să fie folosit, deoarece ar fi putut fi schimbat. În schimb, doriți să utilizați actualul location prop discutat mai jos.

Locație

Locația are proprietăți:

  • pathname
  • search
  • hash
  • state

location.search este folosit pentru a înlocui location.query și trebuie analizat. obisnuiam URLSearchParams să-l analizeze. Deci un URL precum “https://something.com/about?string=’hello’” ar fi analizat ca atare:

...

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

...
Despre.js

În plus, state proprietatea poate fi folosită pentru a trece location-specific state a componentelor prin recuzită. Deci, dacă doriți să transmiteți câteva informații de la o componentă la alta, le puteți folosi astfel:

...
// 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} />
...

Deci, odată ce ajungem la componenta redată de acea cale, vom avea acces la fromDashboard din location.state.fromDashboard.

Meci

match are următoarele proprietăți:

  • params: obține segmentele dinamice ale căii de la adresa URL – de exemplu dacă calea este “/about/:id”, în componentă, accesând this.props.match.params vă va oferi id-ul în adresa URL
  • isExact: adevărat dacă întreaga adresă URL a fost potrivită
  • path: calea din traseele potrivite
  • url: porțiunea potrivită a adresei URL

Integrare Redux

După cum m-am adresat mai devreme, am constatat că, în cazul nostru, nu era nevoie să avem o bibliotecă suplimentară pentru a ne conecta redux cu routerul nostru, mai ales că cazul nostru principal de utilizare pentru acest lucru – Actualizări blocate – a fost acoperit de react router.

Actualizări blocate

În unele cazuri, aplicația nu se actualizează când se schimbă locația. Aceasta se numește „Actualizare blocată”. Acest lucru se poate întâmpla dacă sunt îndeplinite ambele condiții:

  1. Componenta este conectată la Redux prin connect()(Component).
  2. Componenta nu este redată de un <Route>

În aceste cazuri, am încheiat conexiunea componentei cu withRouter.

Acest lucru a permis informațiilor routerului să urmărească componenta atunci când este conectată, astfel încât aplicația să se actualizeze în continuare când starea Redux se modifică.


Si asta e!

Această actualizare mi-a luat peste o săptămână – câteva zile încercând să dau seama cum să o fac, și apoi alte câteva zile pentru a începe efectiv să fac schimbări. Actualizarea la React Router 4 este o schimbare uriașă care nu trebuie luată ușor, dar va face routerul mult mai ușor și mai ușor de utilizat.

Vă rugăm să nu ezitați să comentați / puneți întrebări!