React Router is een essentieel hulpmiddel voor het creëren van navigatie in React-toepassingen, en zijn nieuwste versies blijven de ontwikkelaarservaring verbeteren met nieuwe functies en prestatieverbeteringen. Sinds versie 7 (of andere toekomstige versies), brengt React Router geavanceerde functies zoals geïntegreerde routes en layout routes die helpen bij het bouwen van robuuste en efficiënte webtoepassingen.
Sleutelnieuwe functies in React Router 7 (of nieuwste)
Hier zijn enkele van de belangrijke verbeteringen en functies die zijn geïntroduceerd in de nieuwste versie:
1. Vereenvoudigde route-definitie met data-API’s
Nieuwe data-API’s, zoals loader
en action
, stellen toe om gegevens op een meer declaratieve manier op te halen en te wijzigen binnen routes.
In oudere versies werd gegevensophaling meestal afgehandeld binnen React-componenten met behulp van useEffect
of levenscyclusmethoden van klassecomponenten. Dit leidde vaak tot gegevensophalingslogica die gemengd was met UI-rendering, wat vervelend kon worden.
React Router v5 Voorbeeld
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
function UserPage() {
const { id } = useParams();
const [userData, setUserData] = useState(null);
useEffect(() => {
fetch(`/api/users/${id}`)
.then((response) => response.json())
.then((data) => setUserData(data));
}, [id]);
return (
<div>
<h1>User: {userData?.name}</h1>
</div>
);
}
De nieuwste versies introduceren Loader
API’s, die gegevensophaling direct op het route-niveau mogelijk maken. Dit scheidt de zorgen, vereenvoudigt componenten en maakt betere tegelijkertijd renderen mogelijk.
React Router v7 Voorbeeld
import { useLoaderData } from 'react-router-dom';
export async function userLoader({ params }) {
const response = await fetch(`/api/users/${params.id}`);
return response.json();
}
function UserPage() {
const userData = useLoaderData();
return (
<div>
<h1>User: {userData.name}</h1>
</div>
);
}
// Route Configuration
<Route path="/users/:id" element={<UserPage />} loader={userLoader} />
Verschil
In React Router 7, de data fetch logic (userLoader
) is gedecoupled van het component, waardoor de componenten zich puur richten op renderen. Deze aanpak maakt het ook mogelijk om data voor te fetchen voordat het component rendert, wat leidt tot een betere gebruikerservaring en soepelere overgangen.
2. Error Boundaries Per Route
Eén van de nuttige functies die zijn geïntroduceerd in React Router 7 (of nieuwere versies) is de mogelijkheid om Error Boundaries per route te definiëren. Dit stelt ontwikkelaars in staat om fouten op een meer gedetailleerd niveau te behandelen. In plaats van één enkele globale error boundary voor de hele applicatie, kun je error boundaries definiëren die specifiek zijn voor afzonderlijke routes, waardoor foutafhandeling flexibeler en lokaal wordt. Gedetailleerde foutafhandeling op het routelevel is nu mogelijk.
In oudere versies was foutafhandeling globaal of beheerd op het componentniveau. Dit vereiste dat ontwikkelaars alle mogelijke fouten op één plek behandelden of complexe logica introduceerden in verschillende componenten. Zoals vermeld in het voorbeeld hieronder, is de ErrorBoundary
globaal omdat het de hele Router
omvat, wat betekent dat het fouten van alle routes binnen de app zal vangen.
React Router v5 Voorbeeld
function App() {
return (
<ErrorBoundary>
<Router>
<Route path="/" exact component={HomePage} />
<Route path="/about" component={AboutPage} />
</Router>
</ErrorBoundary>
);
}
React Router 7 introduceert error boundaries op het routelevel, waardoor het mogelijk is om fouten voor specifieke routes te behandelen. Dit biedt meer gedetailleerde controle over hoe fouten worden beheerd en weergegeven.
React Router v7 Voorbeeld
import { useRouteError } from 'react-router-dom';
function ErrorBoundary() {
const error = useRouteError();
return <div>Error: {error.message}</div>;
}
<Route path="/users/:id" element={<UserPage />} errorElement={<ErrorBoundary />} />
Verschil
Foutafhandeling in React Router 7 is modulairder en gelokaliseerder. Elke route kan zijn eigen foutafhandelingslogica definiëren, wat de gebruikerservaring verbetert wanneer verschillende delen van de app falen.
3. Betere Afhandeling van Layout Routes
Layout routes worden geïntroduceerd die consistentie in layoutbeheer mogelijk maken over verschillende delen van de app, wat codeverdubbeling vermindert.
In React Router v5 moesten layouts zoals headers, footers of sidebars handmatig worden verdubbeld in elke route of component. Dit betekende dat ontwikkelaars vaak layoutcomponenten (bijvoorbeeld Header
, Footer
) direct in de App
-component plaatsten of ze herhaalden over verschillende routehandlers, zoals in jouw voorbeeld.
React Router v5 Voorbeeld
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Header from './Header';
import Footer from './Footer';
import HomePage from './HomePage';
import AboutPage from './AboutPage';
function App() {
return (
<Router>
<Header />
<Route path="/" exact component={HomePage} />
<Route path="/about" component={AboutPage} />
<Footer />
</Router>
);
}
React Router 7 introduceert layout routes, waar je gedeelde layouts kunt definiëren die geneste routes omringen, waardoor codeverdubbeling wordt geëlimineerd en een betere structuur wordt gewaarborgd.
React Router v7 Voorbeeld
import { Outlet } from 'react-router-dom';
function SharedLayout() {
return (
<div>
<header>Header Content</header>
<main>
<Outlet /> {/* Nested routes will render here */}
</main>
<footer>Footer Content</footer>
</div>
);
}
// Route Configuration with Layout
<Route path="/" element={<SharedLayout />}>
<Route index element={<HomePage />} />
<Route path="about" element={<AboutPage />} />
</Route>
verschil
Layout routes bieden een schone, herbruikbare manier om gedeelde layouts toe te passen over meerdere routes, zonder code te herhalen. Outlet
fungeert als een placeholder voor child routes, waardoor het veel gemakkelijker is om layouts te beheren.
4. Verbeterde Geneste Routerfunctionaliteiten
Er zijn efficiëntere manieren om geneste routes te hanteren, inclusief het overerven van layoutelementen en betere gegevensophalingsstrategieën.
In oudere versies waren geneste routes mogelijk, maar de instelling was minder handig. Je moest expliciet de geneste routes binnen de oudercomponent afhandelen met behulp van useRouteMatch()
om het huidige pad te verkrijgen, en vervolgens handmatig de geneste routes binnen de oudercomponent definiëren. Deze benadering kan snel omslachtig worden, vooral voor complexe toepassingen met meerdere lagen van geneste routes.
React Router v5 Voorbeeld
import { Route, useRouteMatch } from 'react-router-dom';
function Dashboard() {
const { path } = useRouteMatch();
return (
<div>
<h1>Dashboard</h1>
<Route path={`${path}/overview`} component={Overview} />
<Route path={`${path}/settings`} component={Settings} />
</div>
);
}
<Route path="/dashboard" component={Dashboard} />
In React Router 7 zijn geneste routes nu declaratief geconfigureerd, direct binnen de routeconfiguratie, waardoor de routingstructuur eenvoudiger en de code leesbaarder wordt.
React Router v7 Voorbeeld
import { Outlet } from 'react-router-dom';
function DashboardLayout() {
return (
<div>
<h1>Dashboard</h1>
<Outlet /> {/* Nested routes will render here */}
</div>
);
}
// Route Configuration
<Route path="/dashboard" element={<DashboardLayout />}>
<Route path="overview" element={<Overview />} />
<Route path="settings" element={<Settings />} />
</Route>
verschil
In React Router 7 zijn geneste routes eenvoudiger te beheren omdat ze worden gedefinieerd op het niveau van de routeconfiguratie met behulp van het Outlet
component. Deze structuur bevordert een duidelijke scheiding tussen lay-out en inhoud.
5. Verbeterde Suspense Integratie
Nu is er betere ondersteuning voor React 18’s Suspense
en gelijktijdig renderen voor een vloeiendere laadervaring.
In oudere versies werd suspense alleen ondersteund voor lazy-loaded componenten, wat zijn nut beperkte voor complexe gegevensophalingscenario’s.
React Router v5 Voorbeeld
import React, { Suspense, lazy } from 'react';
const HomePage = lazy(() => import('./HomePage'));
<Suspense fallback={<div>Loading</div>}>
<Route path="/" component={HomePage} />
</Suspense>
React Router 7 integreert Suspense
met zijn Loader en Action APIs, waardoor een gladde, gelijktijdige gegevensophaling mogelijk is met minimale inspanning.
React Router v7 Voorbeeld
import { Suspense } from 'react';
import { Route, Routes } from 'react-router-dom';
function App() {
return (
<Suspense fallback={<div>Loading</div>}>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
</Routes>
</Suspense>
);
}
verschil
React Router 7 maakt gebruik van Suspense
voor zowel lui geladen componenten als gegevensophaling, waardoor soepelere overgangen en een responsievere gebruikersinterface mogelijk zijn.
Conclusie
React Router 7 (of de nieuwste versie) verbetert aanzienlijk het routing in React-toepassingen door verschillende krachtige functies te introduceren. De nieuwe Loader en Action APIs maken declaratieve gegevensophaling mogelijk, waardoor de datalogica van componenten wordt gescheiden voor schonere code. Layout Routes stroomlijnen het beheer van gedeelde lay-outs, redundantie verminderend. Nested routes zijn efficiënter en intuïtiever, waardoor een duidelijker structuur ontstaat. Bovendien bieden foutgrenzen per route fijnmazige foutafhandeling, wat de betrouwbaarheid verbetert. Volledige integratie met React Suspense
ondersteunt gladde gegevensladen en gebruikerservaringen. Samen vereenvoudigen deze verbeteringen de ontwikkeling van complexe, schaalbare en prestatiegerichte React-toepassingen, waardoor React Router 7 een aanzienlijke upgrade is ten opzichte van eerdere versies.
Source:
https://dzone.com/articles/why-react-router-7-is-a-game-changer-for-react-devs