Hitchhiker's Guide to React Router v4: Grok React Router på 20 minutter

Hej kollega React Hitchhiker! Vil du have en tur ind i React Router? Hop ind. Lad os gå!

For at forstå filosofien bag React Router skal vi vide, hvad en SPA (Single-Page Application) er.

Hvad er en applikation med en enkelt side?

Dybest set er det en webapplikation eller et websted, der interagerer med brugeren ved dynamisk at omskrive den aktuelle side i stedet for at indlæse hele nye sider fra en server.

Hvorfor er det så godt ?!

1. undgår afbrydelse af brugeroplevelsen mellem på hinanden følgende sider

2. får applikationen til at opføre sig mere som en desktop-applikation

3. alle kodressourcerne indlæses dynamisk og føjes til siden efter behov, normalt som svar på brugerhandlinger

4. fordi det er kewl og kewl og ekstra ultra-wide-4K-niveau-of-kewl. ?

SPA'er er en industristandard nu, og mange virksomheder er i en søgen efter at finde programmører til at udvikle deres projekter.

Hvad er React Router?

React Router er et værktøj, der giver dig mulighed for at håndtere ruter.

Da du har at gøre med en SPA, har du brug for en måde at udløse indholdet, der er indlæst på skærmen. React Router introducerer et koncept kaldet “Dynamic Routing”, som adskiller sig meget fra den “Static Routing” vi er vant til.

Når du har at gøre med "Statisk routing", erklærer du dine ruter som en del af initialiseringen af ​​din app, inden nogen gengivelse finder sted (Rails, Express, Ember, Angular osv.).

"Dynamisk routing" betyder, at routing finder sted, når din app gengives, ikke i en konfiguration eller konvention uden for en kørende app.

React Router v4 går ind for og implementerer en komponentbaseret tilgang til routing.

Det giver forskellige routingkomponenter i henhold til applikationens og platformens behov.

I dette specifikke tilfælde skal vi udforske   fordi vi ønsker at bruge “dynamisk routing” i en “webapp” -kontekst og lade de andre være under andre omstændigheder.

Hvem oprettede React Router?

Disse to fantastiske mennesker, Michael Jackson og Ryan Florence. Og de fortjener masser, masser af klapper! Sammen startede de React Training.

I dag skal du rette mig, hvis jeg tager fejl, de fulgte adskilte stier:

Michael Jackson fortsætter med at udvikle React Training.

Ryan Florence oprettede Reach.Tech.

Har React Router noget at gøre med Redux?

Nej. Selvom de typisk vises sammen.

Er du sikker? Ja ? Jeg er sikker ?

De er begge gode og uundværlige værktøjer, og da de er komponenter af højere ordre (dybest set JavaScript-funktioner, der tager en komponent og returnerer en ny), så det er almindeligt at finde dem "sammensat" sammen.

Opsætning, lad os få vores hænder beskidte

For at guide dig gennem denne proces bruger vi Create React App (CRA).

I sidste ende har du en ren kedelplade til at opbygge enkle websteder.

Hvis React eller Create React App med en chance er uden for din rækkevidde, anbefaler jeg, at du først kommer ind i dem og derefter kommer tilbage med en kop kaffe.

Okay, for dem der stod sammen med mig: efter installation af CRA skal du installere React-router-pakken.

Hvis du bruger npm, skal du bare åbne din terminal, skal du gå til din CRA-mappe og skrive:

npm i -S react-router-dom

eller

yarn add react-router-dom-hvis du bruger garn som din pakkehåndtering.

Bare for at kontrollere din pakke.jsonog sørg for, at alt er okay, her er min:

Som du kan se? På dette tidspunkt har vi react-router-dom som en afhængighed.

Udført, npm eller garn start og ...

Bang! Vi kører på Ma!

Den app, vi bygger

Lad os lave en enkel personlig webside med en navigationslinje, der giver brugeren mulighed for at skifte mellem indhold. Vores hjemmeside vil have tre hovedsektioner kaldet Hjem , Om og emner .

Den NavBar vil være en allestedsnærværende komponent mens Forside , Om og emner vil blive gjort under ifølge ruterne valgt.

Ser du browserens URL: localhost: 3000 / home i skærmbilledet nedenfor?

Det betyder, at hjem rute udløses og hjem visningen gengives.

Dette vil være vores endelige resultat:

Og dette ...?, Dette er et websted?

? Ja det er!

En nøgen! Bare prøv ikke at føle fordomme over for andre kompleksiteter som styling og så videre! Jeg vil ikke have dig til at blive distraheret med andet end grokking, hvor enkelt det er at implementere React Router v4 .

Så når du er kommet dig efter chokket,? Lad os tage det næste trin og se min /src/index.js-fil.

/src/index.js

index.js er den første fil, der indlæses af CRA, initialiseringspunktet for alt i din app.

Lad os se på, hvad jeg har gjort:

Så hvad laver vi her?

  • Vi importerer komponent fra den afhængighed, vi har installeret, og angiver, at vi vil kalde det fra dette tidspunkt:

import { BrowserRouter as Router } from ‘react-router-dom’;

  • Vi importerer en komponent, oprettet af mig, med de ruter, vi skal bruge på vores websted - rolig lige nu med denne komponent:

import { Routes } from ‘./routes’;

Det komponent træder i stedet for standard CRA  komponent. Det er stort set det samme - jeg kaldte det bare fordi jeg føler det giver mening at gøre koden mere meningsfuld og læsbar.

Du indlæser ikke længere en unik app, men en rutekomponent , der håndterer ruterne og vil udløse montering og gengivelse af de komponenter, der skal indlæses inden for hver rute.

  • Vi omfavner med komponent.

Faktisk, fungerer som en Higher Order-komponent, der kun kender sine børn i fremtiden og interagerer med dem i et bredere omfang, uafhængigt af hvem og hvor mange de er.

Du behøver ikke bekymre dig om, hvordan det fungerer at bruge det. Dette er en meget dybere og avanceret sag.

Bare sørg for at forstå detat React.DOM ikke længere indlæser en simpel app . Det indlæser appen omfavnet af en komponent kaldet, Routerat i en højere instans eller omfang kan interagere med den og med browseren DOM.

Com Ponent

Så dybest set hvad gør routes.js ?

Det starter med at importere React, og et par komponenter kigger vi senere. Bare tænk på dem som simple statsløse komponenter: Forside , Om , TopicList , TopicDetail , NavBar og NoMatch .

Det importerer også tre komponenter fra reaktor-router-dom- pakken, som vi skal påberåbe:, og .

Efter importen eksporterer vi den statsløse komponent Ruter, der påberåber sig NavBar(som altid vil være på skærmen) og a komponent.

Hvad gør denne fyr?

Denne komponent gengiver dybest set det første barn eller der matcher browserplaceringen.

Det begynder at teste ting som dette: “er browserens URL i dette sti? Ingen? Okay." Næste rute. “Er browserens URL i denne anden rute? Ingen."

Næste rute. ”Åh, jeg har det! Det er i denne, lad os udløse komponentgengivelsen og afslutte kontrollen nu (jeg er ligeglad med de andre ruter nedenfor ...) ”

Hvis dette tilfældigvis sker:

den anden rute vil aldrig blive udløst, fordi Switch hopper ud, inden den når den. Han tager bare en kop kaffe ... (og jeg også !!!? Tilbage!)

Inde vi definerer hver .

Hver fortæller dette til browseren:

“Hej browser DOM! Hvis vælger mig, fordi din placering er (nøjagtigt) denne, skal du gengive følgende komponent ”.

Eller i andre tilfælde som den nedenfor, står der:

”Hej, browser, hvis det under alle omstændigheder er din valgte mig, fordi placering er / Emner / ”noget” gengiver Komponent Emnedetaljer. Bestemt finder det ud af, hvem der er dette: topicId (variabel) ting, som brugeren beder os om at matche og rute den i overensstemmelse hermed ”.

Okay alle sammen. Fordi har denne standardadfærd for at kontrollere hver rute, skal vi give et tilbagefald, hvis det ikke matcher noget:

Denne sidste rute gengiver simpelthen en standardside, der siger, at ingen rute blev matchet, en slags HTTP 404-fejl.

Husk at her har vi at gøre med en SPA og med "Dynamic Routing", så dette er en simulering, som om vi krævede ruter til en server?. Faktisk er vi ikke!

Vi ved bare ikke, hvad vi skal gengive, hvis brugeren for eksempel indsætter noget, der ikke stemmer overens med URL'en som denne: // localhost: 3000 / HelloWorld .

Da denne rute ikke var defineret, leverer vi en NoMatch- komponent til at informere dem om, at ruten ikke eksisterer.

er der, fordi hvis brugeren forsøger at indlæse URL'en uden nogen rute // localhost: 3000 / , ville den få en NoMatch, fordi der ikke er defineret nogen rute til den. Så den bedste måde at håndtere dette på er at gøre brug af  og skub brugeren til ruten til / Hjem, som som standard er vores første skærmbillede af appen.

Hvorfor er dette nødvendigt?

Igen, for normalt vil brugeren starte applikationen ved at skrive den generelle URL og uden den første gengivne komponent ville være . Vi ønsker ikke det, vi vil have, at brugeren omdirigeres til komponent.

Visninger og / eller komponenter

På dette tidspunkt i vores guide vil jeg gerne stoppe lidt for at differentiere en visning fra en komponent. Dette er ikke essensen af ​​denne vejledning, men det giver mening, når jeg viser dig mappestrukturen på min CRA .

Når vi ”tænker i reaktion”, og vi begynder at lave en app, og den begynder at vokse, stopper vi nogle gange, fordi vi føler, at ting ikke er på det rigtige sted.

Dette betyder, at vi er nødt til at give navne til disse ting og holde dem adskilt i forskellige "skuffer" eller "mapper".

Visninger og komponenter er ting, der males på skærmen. Så hvad adskiller den ene ting fra den anden?

Og er synspunkter ikke komponenter? Og komponenter er ikke synspunkter?

Nå, med hensyn til kodningssprog er en visning og en komponent bestemt funktioner eller klasser - statsløse komponenter eller stateful komponenter, som vi kalder det i React lingo.

Så hvad adskiller dem?

En visning har en rute. Inde i denne visning kan du gengive mange komponenter.

En komponent er normalt en abstraktion, der kan påberåbes mange gange i forskellige synspunkter. Det kan være en knap, en formular, et diagram. Det kan endda være en mere kompleks ting, mens en visning er unik og har en rute.

Dette er et meget simpelt koncept, der skal forstås i starten, så snart vi begynder at lave en app, der er så lille som en personlig hjemmeside.

Lad os se på min CRA-mappestruktur:

Så som du kan se, holder jeg - og 99% af verden - gerne af appelsiner og pærer i forskellige kurve. Og det gør du også! Jeg tror på dig! Jeg stoler på dig!

Der er mange mønstre for, hvordan man organiserer disse ting, og en masse diskussion starter, når vi introducerer flere pakker som Redux, der forvandler lidt arkitekturen til appen, eller når vi vil male på skærmen Dashboards, Widgets, Cykling Grise eller mere underlige ting ...

Men for at differentiere begreber skal du se nøje på Visninger og komponenter.

Home , About , TopicList og NoMatch er visninger. De har deres egne rette ruter, der udløser dem.

NavBar er en allestedsnærværende komponent, der altid påberåbes. Det har ikke en rute.

TopicDetails er en komponent, der viser emneoplysninger, når TopicList /: topicId- ruten udløses. Det er en genanvendelig komponent, der kan importeres til andre steder og refaktureres eller udvides. Det har ikke en bestemt rute.

Hjemmet / Om visningerne

Inde i mappen Hjem har jeg en index.js og en Home.js- fil.

At have et index.js til at eksportere de andre filer er en god praksis. Stol bare på mig eller tag med vin, fordi dette bliver en lang snak?

... åh, lad os bare drikke vinen, så taler vi senere! ?

Dette er en simpel visning, der kun eksporterer titlen. Visningen Om er lig med denne.

Lad os nu se på TopicList View, fordi det er lidt anderledes.

TopicList og TopicDetail-visninger

TopicList View har denne detalje i håndtering af forskellige ruter. Husk det / Emne /: topicId rute det fortalte at lade TopicDetail håndtere?

Her er vi med det.

TopicList modtager {match} som en prop. Lad ikke destruktureringsfunktionen skræmme dig. Vi kunne simpelthen modtage rekvisitter og kalde props.match . Dette er simpelthen, hvordan alle de seje børn i dag ødelægger rekvisitter for at forbedre læsbarheden og reagere flow. Jeg kan også godt lide det! Dette er som at hente en kasse med din mobil indeni eller afhente mobilen direkte. Faktisk blev det holdt inde i kassen, men i øjeblikket behøver du kun at kontrollere din e-mail? så lad kassen blive, hvor den er! Tag det ikke med dig på arbejde!

Lad os alligevel holde fokus på kode.

I denne fil importerer vi en komponent fra React Router kaldet {Link}, fordi vi vil oprette links?

Vi modtager et match fra den rute, vi har valgt, når vi har klikket på Emner, og vi gengiver en ikke-ordnet liste med 3 muligheder: Emne1 , Emne2 og Emne3 .

Dybest set, hvis brugeren vælger Topic1 Link på skærmen,vil skubbe browserens URL til den sti / Emner / Emne1 .

Hvad sker der nu? og opdage, at URL'en er ændret, og se på deres info for at kontrollere, hvilken rute der skal fyres. Så de opdager, at nu den udløste rute er `den for / Emner /: topicId og udløser gengivelse af TopicDetail . TopicDetail vil gøre Topic1 detaljer.

TopicDetail modtager match fra routeren og gengiver topicId placeret på match.params.topicId .

NavBar-komponenten

Den NavBar komponent har en særlig rolle her, fordi det er allestedsnærværende.

Dens funktion er at give brugeren mulighed for at navigere på webstedet og vise de tilgængelige sektioner (ruter).

Som du har set i starten, er det indeni men udenfor så enhver visning vil altid blive sammensat med NavBar ovenpå.

Som du kan se, er dens rolle grundlæggende. Det leverer kun og fortæller at spørge for at udløse det valgte og gengiv det på skærmen.

Sidst men ikke mindst

Jeg tror, ​​at du på dette tidspunkt sandsynligvis har en grundlæggende forståelse af, hvordan React Router fungerer og kan bruges til at lave et simpelt websted.

Hvis du vil kontrollere koden eller teste den, kan du trække min repo, tilgængelig på GitHub.

Bibliografi

For at lave denne artikel har jeg brugt dokumentet React Router, som du kan finde her.

Alle de andre websteder, jeg har brugt, er knyttet sammen med dokumentet for at tilføje info eller give kontekst til det, jeg har forsøgt at forklare dig.

Denne artikel er del 1 af en serie kaldet "Hitchhiker's Guide to React Router v4." Del 2–4 kommer til freeCodeCamp i hele denne uge!

  • Del II: [match, placering, historie] - dine bedste venner!
  • Del III: rekursive stier, til uendelig og videre!
  • Del IV: rutekonfiguration, den skjulte værdi ved at definere et rutekonfigurationsarray

Mange tak!