Deutsch

Entdecken Sie essenzielle Navigationsmuster mit React Router v6. Lernen Sie deklaratives Routing, dynamische Routen, programmatische Navigation, verschachtelte Routen und Datenladestrategien für die Erstellung robuster und benutzerfreundlicher Webanwendungen.

React Router v6: Navigationsmuster für moderne Web-Apps meistern

React Router v6 ist eine leistungsstarke und flexible Routing-Bibliothek für React-Anwendungen. Sie ermöglicht es Ihnen, Single-Page-Anwendungen (SPAs) mit einem nahtlosen Benutzererlebnis zu erstellen, indem die Navigation ohne vollständige Seitenneuladungen verwaltet wird. Dieser Blogbeitrag befasst sich mit den wesentlichen Navigationsmustern von React Router v6 und vermittelt Ihnen das Wissen und die Beispiele, um robuste und benutzerfreundliche Webanwendungen zu erstellen.

Grundlagen von React Router v6 verstehen

Bevor wir uns mit spezifischen Mustern befassen, wollen wir einige grundlegende Konzepte wiederholen:

1. Deklaratives Routing mit <Routes> und <Route>

Das Fundament von React Router v6 ist das deklarative Routing. Sie definieren Ihre Routen mit den Komponenten <Routes> und <Route>. Die <Routes>-Komponente dient als Container für Ihre Routen, und die <Route>-Komponente definiert eine spezifische Route sowie die Komponente, die gerendert werden soll, wenn diese Route mit der aktuellen URL übereinstimmt.

Beispiel: Grundlegende Routenkonfiguration

Hier ist ein grundlegendes Beispiel für die Einrichtung von Routen für eine einfache Anwendung:


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;

In diesem Beispiel definieren wir drei Routen:

Die BrowserRouter-Komponente ermöglicht das auf der Browser-Historie basierende Routing. React Router gleicht die aktuelle URL mit den definierten Routen ab und rendert die entsprechende Komponente.

2. Dynamische Routen mit URL-Parametern

Dynamische Routen ermöglichen es Ihnen, Routen zu erstellen, die unterschiedliche Werte in der URL verarbeiten können. Dies ist nützlich, um Inhalte basierend auf einem eindeutigen Bezeichner wie einer Produkt-ID oder einer Benutzer-ID anzuzeigen. React Router v6 verwendet das :-Symbol, um URL-Parameter zu definieren.

Beispiel: Anzeige von Produktdetails

Angenommen, Sie haben eine E-Commerce-Anwendung und möchten Details für jedes Produkt basierend auf seiner ID anzeigen. Sie können eine dynamische Route wie diese definieren:


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

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

  // Produktdetails basierend auf productId abrufen
  // ...

  return (
    

Product Details

Product ID: {productId}

{/* Produktdetails hier anzeigen */}
); } function App() { return ( } /> ); } export default App;

In diesem Beispiel:

Internationalisierungsbeispiel: Umgang mit Sprachcodes

Für eine mehrsprachige Website könnten Sie eine dynamische Route verwenden, um Sprachcodes zu verarbeiten:


} />

Diese Route würde URLs wie /de/about, /fr/about und /es/about entsprechen. Der lang-Parameter kann dann verwendet werden, um die entsprechenden Sprachressourcen zu laden.

3. Programmatische Navigation mit useNavigate

Während deklaratives Routing ideal für statische Links ist, müssen Sie oft programmatisch navigieren, basierend auf Benutzeraktionen oder Anwendungslogik. React Router v6 stellt dafür den useNavigate-Hook bereit. useNavigate gibt eine Funktion zurück, mit der Sie zu verschiedenen Routen navigieren können.

Beispiel: Weiterleitung nach dem Absenden eines Formulars

Angenommen, Sie haben ein Formular, das abgesendet wird, und möchten den Benutzer nach erfolgreicher Übermittlung auf eine Erfolgsseite weiterleiten:


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

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

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

    // Formulardaten senden
    // ...

    // Nach erfolgreicher Übermittlung zur Erfolgsseite weiterleiten
    navigate("/success");
  };

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

In diesem Beispiel:

Zustand (State) während der Navigation übergeben

Sie können auch einen Zustand (State) zusammen mit der Navigation übergeben, indem Sie das zweite Argument von navigate verwenden:


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

Dies ermöglicht es Ihnen, Daten an die Zielkomponente zu übergeben, auf die mit dem useLocation-Hook zugegriffen werden kann.

4. Verschachtelte Routen und Layouts

Verschachtelte Routen ermöglichen es Ihnen, hierarchische Routing-Strukturen zu erstellen, bei denen eine Route in einer anderen verschachtelt ist. Dies ist nützlich, um komplexe Anwendungen mit mehreren Navigationsebenen zu organisieren. Es hilft bei der Erstellung von Layouts, bei denen bestimmte UI-Elemente in einem Bereich der Anwendung konsistent vorhanden sind.

Beispiel: Benutzerprofil-Bereich

Angenommen, Sie haben einen Benutzerprofil-Bereich mit verschachtelten Routen zur Anzeige der Profilinformationen, Einstellungen und Bestellungen des Benutzers:


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

function Profile() {
  return (
    

User Profile

  • Profile Information
  • Settings
  • Orders
} /> } /> } />
); } function ProfileInformation() { return

Profile Information Component

; } function Settings() { return

Settings Component

; } function Orders() { return

Orders Component

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

In diesem Beispiel:

Das * in der übergeordneten Route ist entscheidend; es bedeutet, dass die übergeordnete Route auf jeden Unterpfad passen soll, wodurch die verschachtelten Routen innerhalb der Profile-Komponente korrekt zugeordnet werden können.

5. Umgang mit "Nicht gefunden" (404)-Fehlern

Es ist unerlässlich, Fälle zu behandeln, in denen der Benutzer zu einer nicht existierenden Route navigiert. React Router v6 macht dies mit einer Catch-All-Route einfach.

Beispiel: Implementierung einer 404-Seite


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

function NotFound() {
  return (
    

404 - Not Found

The page you are looking for does not exist.

Go back to home
); } function App() { return ( } /> } /> } /> ); }

In diesem Beispiel:

6. Datenladestrategien mit React Router v6

React Router v6 enthält keine integrierten Datenlademechanismen wie sein Vorgänger (React Router v5 mit `useRouteMatch`). Es bietet jedoch die Werkzeuge, um verschiedene Datenladestrategien effektiv umzusetzen.

Option 1: Daten in Komponenten abrufen

Der einfachste Ansatz ist, Daten direkt in der Komponente abzurufen, die die Route rendert. Sie können den useEffect-Hook verwenden, um Daten abzurufen, wenn die Komponente eingehängt wird oder wenn sich die URL-Parameter ändern.


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 error! status: ${response.status}`);
        }
        const data = await response.json();
        setProduct(data);
        setLoading(false);
      } catch (e) {
        setError(e);
        setLoading(false);
      }
    }

    fetchProduct();
  }, [productId]);

  if (loading) return 

Loading...

; if (error) return

Error: {error.message}

; if (!product) return

Product not found

; return (

{product.name}

{product.description}

); } export default ProductDetails;

Dieser Ansatz ist unkompliziert, kann aber zu Code-Duplizierung führen, wenn Sie Daten in mehreren Komponenten abrufen müssen. Er ist auch weniger effizient, da das Datenladen erst nach dem Einhängen der Komponente beginnt.

Option 2: Einen benutzerdefinierten Hook für das Datenladen verwenden

Um Code-Duplizierung zu reduzieren, können Sie einen benutzerdefinierten Hook erstellen, der die Logik für das Datenladen kapselt. Dieser Hook kann dann in mehreren Komponenten wiederverwendet werden.


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 error! 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;

Dann können Sie diesen Hook in Ihren Komponenten verwenden:


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 

Loading...

; if (error) return

Error: {error.message}

; if (!product) return

Product not found

; return (

{product.name}

{product.description}

); } export default ProductDetails;

Option 3: Eine Routing-Bibliothek mit Datenladefähigkeiten verwenden (TanStack Router, Remix)

Bibliotheken wie TanStack Router und Remix bieten integrierte Datenlademechanismen, die sich nahtlos in das Routing integrieren. Diese Bibliotheken bieten oft Funktionen wie:

Die Verwendung einer solchen Bibliothek kann das Laden von Daten drastisch vereinfachen und die Leistung verbessern, insbesondere bei komplexen Anwendungen.

Serverseitiges Rendern (SSR) und Statische Seitengenerierung (SSG)

Für eine verbesserte SEO und Ladeleistung beim ersten Aufruf sollten Sie die Verwendung von SSR oder SSG mit Frameworks wie Next.js oder Gatsby in Betracht ziehen. Diese Frameworks ermöglichen es Ihnen, Daten auf dem Server oder während der Build-Zeit abzurufen und dem Client vorgerendertes HTML bereitzustellen. Dadurch entfällt die Notwendigkeit, dass der Client beim ersten Laden Daten abrufen muss, was zu einem schnelleren und SEO-freundlicheren Erlebnis führt.

7. Arbeiten mit verschiedenen Router-Typen

React Router v6 bietet verschiedene Router-Implementierungen für unterschiedliche Umgebungen und Anwendungsfälle:

Wählen Sie den Router-Typ, der am besten zu den Anforderungen und der Umgebung Ihrer Anwendung passt.

Fazit

React Router v6 bietet eine umfassende und flexible Routing-Lösung für React-Anwendungen. Durch das Verstehen und Anwenden der in diesem Blogbeitrag besprochenen Navigationsmuster können Sie robuste, benutzerfreundliche und wartbare Webanwendungen erstellen. Vom deklarativen Routing mit <Routes> und <Route> über dynamische Routen mit URL-Parametern, programmatische Navigation mit useNavigate bis hin zu effektiven Datenladestrategien – React Router v6 ermöglicht es Ihnen, nahtlose Navigationserlebnisse für Ihre Benutzer zu schaffen. Erwägen Sie die Erkundung fortgeschrittener Routing-Bibliotheken und SSR/SSG-Frameworks für noch mehr Kontrolle und Leistungsoptimierung. Denken Sie daran, diese Muster an Ihre spezifischen Anwendungsanforderungen anzupassen und stets ein klares und intuitives Benutzererlebnis zu priorisieren.