Norsk

Utforsk essensielle navigeringsmønstre med React Router v6. Lær deklarativ ruting, dynamiske ruter, programmatisk navigering, nestede ruter og datainnlastingsstrategier for å bygge robuste og brukervennlige webapplikasjoner.

React Router v6: Mestre navigeringsmønstre for moderne webapplikasjoner

React Router v6 er et kraftig og fleksibelt rutingsbibliotek for React-applikasjoner. Det lar deg lage enkeltsideapplikasjoner (SPA-er) med en sømløs brukeropplevelse ved å håndtere navigasjon uten fullstendig sideinnlasting. Dette blogginnlegget vil dykke ned i essensielle navigeringsmønstre ved hjelp av React Router v6, og gi deg kunnskapen og eksemplene for å bygge robuste og brukervennlige webapplikasjoner.

Forstå kjernekonseptene i React Router v6

Før vi dykker ned i spesifikke mønstre, la oss gå gjennom noen grunnleggende konsepter:

1. Deklarativ ruting med <Routes> og <Route>

Grunnlaget for React Router v6 ligger i deklarativ ruting. Du definerer rutene dine ved hjelp av <Routes>- og <Route>-komponentene. <Routes>-komponenten fungerer som en container for rutene dine, og <Route>-komponenten definerer en spesifikk rute og komponenten som skal rendres når den ruten samsvarer med den nåværende URL-en.

Eksempel: Grunnleggende rutekonfigurasjon

Her er et grunnleggende eksempel på hvordan du setter opp ruter for en enkel applikasjon:


import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";
import Contact from "./pages/Contact";

function App() {
  return (
    
      
        } />
        } />
        } />
      
    
  );
}

export default App;

I dette eksempelet definerer vi tre ruter:

BrowserRouter-komponenten muliggjør ruting basert på nettleserhistorikk. React Router sammenligner den nåværende URL-en med de definerte rutene og rendrer den tilsvarende komponenten.

2. Dynamiske ruter med URL-parametere

Dynamiske ruter lar deg lage ruter som kan håndtere forskjellige verdier i URL-en. Dette er nyttig for å vise innhold basert på en unik identifikator, for eksempel en produkt-ID eller en bruker-ID. React Router v6 bruker :-symbolet for å definere URL-parametere.

Eksempel: Vise produktdetaljer

La oss si du har en e-handelsapplikasjon og ønsker å vise detaljer for hvert produkt basert på ID-en. Du kan definere en dynamisk rute som dette:


import { BrowserRouter, Routes, Route, useParams } from "react-router-dom";

function ProductDetails() {
  const { productId } = useParams();

  // Hent produktdetaljer basert på productId
  // ...

  return (
    

Produktdetaljer

Produkt-ID: {productId}

{/* Vis produktdetaljer her */}
); } function App() { return ( } /> ); } export default App;

I dette eksempelet:

Eksempel på internasjonalisering: Håndtering av språkkoder

For en flerspråklig nettside kan du bruke en dynamisk rute for å håndtere språkkoder:


} />

Denne ruten vil matche URL-er som /en/about, /fr/about og /es/about. lang-parameteren kan deretter brukes til å laste inn de riktige språkressursene.

3. Programmatisk navigering med useNavigate

Selv om deklarativ ruting er flott for statiske lenker, må du ofte navigere programmatisk basert på brukerhandlinger eller applikasjonslogikk. React Router v6 tilbyr useNavigate-hooken for dette formålet. useNavigate returnerer en funksjon som lar deg navigere til forskjellige ruter.

Eksempel: Omdirigere etter skjemainnsending

La oss si du har en skjemainnsending og ønsker å omdirigere brukeren til en suksess-side etter at skjemaet er sendt inn:


import { useNavigate } from "react-router-dom";

function MyForm() {
  const navigate = useNavigate();

  const handleSubmit = async (event) => {
    event.preventDefault();

    // Send skjemadata
    // ...

    // Omdiriger til suksess-siden etter vellykket innsending
    navigate("/success");
  };

  return (
    
{/* Skjemafelter */}
); } export default MyForm;

I dette eksempelet:

Sende med 'state' under navigering

Du kan også sende med 'state' sammen med navigeringen ved å bruke det andre argumentet til navigate:


navigate("/confirmation", { state: { orderId: "12345" } });

Dette lar deg sende data til målkomponenten, som kan nås ved hjelp av useLocation-hooken.

4. Nestede ruter og layouter

Nestede ruter lar deg lage hierarkiske rutingsstrukturer, der en rute er nestet inne i en annen. Dette er nyttig for å organisere komplekse applikasjoner med flere nivåer av navigasjon. Dette hjelper med å lage layouter der visse UI-elementer er konsekvent til stede på tvers av en del av applikasjonen.

Eksempel: Brukerprofilseksjon

La oss si at du har en brukerprofilseksjon med nestede ruter for å vise brukerens profilinformasjon, innstillinger og ordrer:


import { BrowserRouter, Routes, Route, Link } from "react-router-dom";

function Profile() {
  return (
    

Brukerprofil

  • Profilinformasjon
  • Innstillinger
  • Ordrer
} /> } /> } />
); } function ProfileInformation() { return

Profilinformasjon-komponent

; } function Settings() { return

Innstillinger-komponent

; } function Orders() { return

Ordrer-komponent

; } function App() { return ( } /> ); } export default App;

I dette eksempelet:

* i den overordnede ruten er avgjørende; den signaliserer at den overordnede ruten skal matche enhver underbane, slik at de nestede rutene kan matches riktig inne i Profile-komponenten.

5. Håndtere «Ikke funnet» (404)-feil

Det er viktig å håndtere tilfeller der brukeren navigerer til en rute som ikke eksisterer. React Router v6 gjør dette enkelt med en «catch-all»-rute.

Eksempel: Implementere en 404-side


import { BrowserRouter, Routes, Route, Link } from "react-router-dom";

function NotFound() {
  return (
    

404 - Ikke funnet

Siden du leter etter, finnes ikke.

Gå tilbake til forsiden
); } function App() { return ( } /> } /> } /> ); }

I dette eksempelet:

6. Strategier for datainnlasting med React Router v6

React Router v6 inkluderer ikke innebygde datainnlastingsmekanismer som sin forgjenger (React Router v5 med `useRouteMatch`). Imidlertid gir den verktøyene til å implementere ulike datainnlastingsstrategier effektivt.

Alternativ 1: Hente data i komponenter

Den enkleste tilnærmingen er å hente data direkte i komponenten som rendrer ruten. Du kan bruke useEffect-hooken for å hente data når komponenten monteres eller når URL-parametrene endres.


import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";

function ProductDetails() {
  const { productId } = useParams();
  const [product, setProduct] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchProduct() {
      try {
        const response = await fetch(`/api/products/${productId}`);
        if (!response.ok) {
          throw new Error(`HTTP-feil! Status: ${response.status}`);
        }
        const data = await response.json();
        setProduct(data);
        setLoading(false);
      } catch (e) {
        setError(e);
        setLoading(false);
      }
    }

    fetchProduct();
  }, [productId]);

  if (loading) return 

Laster...

; if (error) return

Feil: {error.message}

; if (!product) return

Produkt ikke funnet

; return (

{product.name}

{product.description}

); } export default ProductDetails;

Denne tilnærmingen er enkel, men kan føre til duplisering av kode hvis du trenger å hente data i flere komponenter. Det er også mindre effektivt fordi datainnhentingen starter først etter at komponenten er montert.

Alternativ 2: Bruke en egendefinert hook for datainnhenting

For å redusere kodeduplisering kan du lage en egendefinert hook som innkapsler logikken for datainnhenting. Denne hooken kan deretter gjenbrukes i flere komponenter.


import { useState, useEffect } from "react";

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`HTTP-feil! Status: ${response.status}`);
        }
        const json = await response.json();
        setData(json);
        setLoading(false);
      } catch (e) {
        setError(e);
        setLoading(false);
      }
    }

    fetchData();
  }, [url]);

  return { data, loading, error };
}

export default useFetch;

Deretter kan du bruke denne hooken i komponentene dine:


import { useParams } from "react-router-dom";
import useFetch from "./useFetch";

function ProductDetails() {
  const { productId } = useParams();
  const { data: product, loading, error } = useFetch(`/api/products/${productId}`);

  if (loading) return 

Laster...

; if (error) return

Feil: {error.message}

; if (!product) return

Produkt ikke funnet

; return (

{product.name}

{product.description}

); } export default ProductDetails;

Alternativ 3: Bruke et rutingsbibliotek med datainnhentingsfunksjoner (TanStack Router, Remix)

Biblioteker som TanStack Router og Remix tilbyr innebygde datainnhentingsmekanismer som integreres sømløst med ruting. Disse bibliotekene tilbyr ofte funksjoner som:

Å bruke et slikt bibliotek kan drastisk forenkle datainnlasting og forbedre ytelsen, spesielt for komplekse applikasjoner.

Serverside-rendring (SSR) og statisk sidegenerering (SSG)

For forbedret SEO og ytelse ved første innlasting, bør du vurdere å bruke SSR eller SSG med rammeverk som Next.js eller Gatsby. Disse rammeverkene lar deg hente data på serveren eller under byggeprosessen og servere forhåndsrendret HTML til klienten. Dette eliminerer behovet for at klienten må hente data ved første innlasting, noe som resulterer i en raskere og mer SEO-vennlig opplevelse.

7. Jobbe med forskjellige rutertyper

React Router v6 tilbyr forskjellige ruterimplementeringer for å passe til ulike miljøer og bruksområder:

Velg den rutertypen som passer best til applikasjonens krav og miljø.

Konklusjon

React Router v6 tilbyr en omfattende og fleksibel rutingsløsning for React-applikasjoner. Ved å forstå og anvende navigeringsmønstrene som er diskutert i dette blogginnlegget, kan du bygge robuste, brukervennlige og vedlikeholdbare webapplikasjoner. Fra deklarativ ruting med <Routes> og <Route> til dynamiske ruter med URL-parametere, programmatisk navigering med useNavigate, og effektive datainnlastingsstrategier, gir React Router v6 deg kraften til å skape sømløse navigasjonsopplevelser for brukerne dine. Vurder å utforske avanserte rutingsbiblioteker og SSR/SSG-rammeverk for enda større kontroll og ytelsesoptimalisering. Husk å tilpasse disse mønstrene til dine spesifikke applikasjonskrav og alltid prioritere en klar og intuitiv brukeropplevelse.