Tot nu toe hebben we altijd gewerkt met 1 pagina, maar uiteraard bestaan de meeste web applicaties uit verschillende pagina's. Je hebt bijvoorbeeld een lijst pagina waar de data in een lijst wordt getoond, als je dan doorklikt wil je naar een detail pagina gaan. Je wil ook verschillende pagina's gaan aanbieden op andere url's. Zo zal een lijst bijvoorbeeld op het pad /list
staan en de detail op /detail/{id}
. Om dit te doen gaan we gebruik maken van een externe library uit de npm registry: react-router-dom
Het eerste wat we gaan doen is onze games list pagina in een apart component plaatsen, zodat deze code niet meer in de App
component staat. Deze component krijgt later de verantwoordelijkheid voor het tonen van de verschillende pagina's, niet alleen de List
pagina. We maken een nieuwe directory pages
en maken daar een nieuwe directory ListPage
aan. We kopieren de inhoud van het App.tsx
bestand naar een nieuw bestand genaamd ListPage.tsx
en doen hetzelfde met de CSS-module van dit component. Vergeet niet de naam van het component aan te passen de default export.
Momenteel zit de lijst van games nog in het ListPage
component. We willen dit component beschikbaar maken voor alle pagina's dus we gaan de state een niveau hoger plaatsen. Wat wil zeggen dat we deze gaan terug plaatsen in het App
component. We moeten er voor zorgen dat de ListPage
de games list via props laten binnen krijgen. We definiƫren de volgende props voor de ListPage
Je merkt op dat we hier ook de handleAdd
callback handler hebben opgegeven als property van onze ListPage
. De handleAdd
callback handler die hier wordt meegegeven wordt gewoon doorgeven aan het InputView
component.
En het App
component zal er als volgt uit zien.
Merk op dat we de Header
component in de App
component hebben gelaten. We willen de header op elke pagina plaatsen dus we zetten deze dan op dit niveau.
Nu hebben we er voor gezorgd dat we een aparte pagina hebben voor onze lijst van games en dat het App
component verantwoordelijk is voor de lijst van games te beheren (de state bevind zich dus op het hoogste component)
Nu we een aparte pagina hebben voor de lijst gaan we nu de library installeren die het mogelijk maakt om eenvoudig nieuwe pagina's op verschillende routes te introduceren. We installeren react-router met het volgende commando:
Ondertussen is react-router v6 uitgebracht. Dit betekent dat deze instructies niet allemaal nog gelden voor de laatste nieuwe versie. Daarom kan je best v5 installeren.
Omdat we momenteel maar pagina hebben maken we een heel eenvoudige HomePage.
De CSS style van de welcomeText mag je zelf kiezen. Zorg ervoor dat beide bestanden in een src/Pages/HomePage
directory zitten.
Nu gaan we onze App
component aanpassen zodat het de React router library gebruikt om de routes te vast te leggen en te kiezen welke page moet getoond worden bij welke route.
Als je ergens React Router wil gebruiken dan moet het parent component altijd een Router
component zijn.
Er zijn een aantal varianten op deze Router
component zoals BrowserRouter
en HashRouter
. Deze hebben invloed over hoe de urls die worden gegenereerd voor de paden zullen getoond worden. We bekijken deze niet in detail, maar deze zijn belangrijk als je uiteindelijk je applicatie op een externe webserver wil laten lopen.
Route
en Switch
noemen we route matching componenten. Als een Switch
wordt gerendered, wordt er in zijn kind elementen gezocht achter Route
elementen en wordt er gezocht achter het pad dat overeenkomt met de huidige URL. Als het er een vindt, dan rendered hij die Route
en negeert hij alle anderen. Dit betekent dat je altijd de meest specifieke (vaak de langste) eerst moet plaatsen voor de minder specifieke routes.
In ons geval hebben we nu twee routes. De route voor de lijst op /list
en de route voor /
die de HomePage zal laten zien aan de gebruiker. In de Route
componenten plaatsen we hier de componenten die hij zal moeten tonen als naar die route gegaan wordt in je browser.
React Router biedt een <Link>
component aan om links te maken in je applicatie. Overal waar je een Link rendered wordt een anchor (<a>
) tag gerendered in je HTML document.
Je hebt ook nog een speciale versie van de <Link>
component die zichzelf als 'actief' kan renderen als de to
prop overeenkomt met de huidige locatie. Als je de exacte locatie wilt matchen moet je hierbij ook nog exact als prop meegeven.
Zo kunnen we nu een navigatie balk aanmaken in onze header component:
Tot nu toe hebben we altijd routes gebruikt die exacte paden voorstellen. Soms wil je ook aan de hand van de url bepaalde parameters gaan meegeven. Zo willen wij in ons voorbeeld een pad aanmaken waarmee je het detail van een game kan bekijken. We zouden hier graag een url zoals /detail/:id
toelaten waarbij de :id
dus een parameter is. Deze kan bijvoorbeeld /detail/1
of /detail/2
zijn en hiervoor moet altijd hetzelfde component gerendered worden.
Laten we eerst een eenvoudige DetailPage
maken voor deze route:
We moeten dan deze DetailPage
toevoegen aan onze Router
Een parameter in een route wordt aangeven met de naam van de parameter en een :
ervoor. In dit geval is dit /detail/:id
waarvan id de naam van de parameter is.
Om deze parameters uit te kunnen lezen in de DetailPage
kunnen we de useParams
hook gebruiken om deze parameters te kunnen uitlezen.
We kunnen ons ListItem
component aanpassen aan de hand van het Link
component zodat als we op het de game klikken dat we dan naar de detailpagina verwezen worden.