Italiano

Esplora i pattern di navigazione essenziali con React Router v6. Impara il routing dichiarativo, le route dinamiche, la navigazione programmatica, le route annidate e le strategie di caricamento dati per creare applicazioni web robuste e user-friendly.

React Router v6: Padroneggiare i Pattern di Navigazione per le App Web Moderne

React Router v6 è una libreria di routing potente e flessibile per applicazioni React. Permette di creare single-page application (SPA) con un'esperienza utente fluida, gestendo la navigazione senza ricaricare l'intera pagina. Questo articolo approfondirà i pattern di navigazione essenziali utilizzando React Router v6, fornendoti le conoscenze e gli esempi per costruire applicazioni web robuste e facili da usare.

Comprendere i Concetti Fondamentali di React Router v6

Prima di immergerci in pattern specifici, riesaminiamo alcuni concetti fondamentali:

1. Routing Dichiarativo con <Routes> e <Route>

Il fondamento di React Router v6 risiede nel routing dichiarativo. Le route si definiscono utilizzando i componenti <Routes> e <Route>. Il componente <Routes> agisce come un contenitore per le tue route, mentre il componente <Route> definisce una route specifica e il componente da renderizzare quando quella route corrisponde all'URL corrente.

Esempio: Configurazione di Base delle Route

Ecco un esempio di base per configurare le route per una semplice applicazione:


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 questo esempio, definiamo tre route:

Il componente BrowserRouter abilita il routing basato sulla cronologia del browser. React Router confronta l'URL corrente con le route definite e renderizza il componente corrispondente.

2. Route Dinamiche con Parametri URL

Le route dinamiche consentono di creare percorsi che possono gestire valori diversi nell'URL. Ciò è utile per visualizzare contenuti basati su un identificatore univoco, come l'ID di un prodotto o di un utente. React Router v6 utilizza il simbolo : per definire i parametri URL.

Esempio: Visualizzazione dei Dettagli del Prodotto

Supponiamo di avere un'applicazione di e-commerce e di voler visualizzare i dettagli di ogni prodotto in base al suo ID. È possibile definire una route dinamica in questo modo:


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

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

  // Recupera i dettagli del prodotto in base a productId
  // ...

  return (
    

Dettagli Prodotto

ID Prodotto: {productId}

{/* Visualizza i dettagli del prodotto qui */}
); } function App() { return ( } /> ); } export default App;

In questo esempio:

Esempio di Internazionalizzazione: Gestione dei Codici Lingua

Per un sito multilingue, si potrebbe utilizzare una route dinamica per gestire i codici lingua:


} />

Questa route corrisponderebbe a URL come /en/about, /fr/about e /es/about. Il parametro lang può quindi essere utilizzato per caricare le risorse della lingua appropriata.

3. Navigazione Programmatica con useNavigate

Sebbene il routing dichiarativo sia ottimo per i link statici, spesso è necessario navigare in modo programmatico in base alle azioni dell'utente o alla logica dell'applicazione. React Router v6 fornisce l'hook useNavigate a questo scopo. useNavigate restituisce una funzione che permette di navigare verso diverse route.

Esempio: Reindirizzamento dopo l'Invio di un Modulo

Supponiamo di avere un modulo da inviare e di voler reindirizzare l'utente a una pagina di successo dopo che il modulo è stato inviato correttamente:


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

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

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

    // Invia i dati del modulo
    // ...

    // Reindirizza alla pagina di successo dopo l'invio corretto
    navigate("/success");
  };

  return (
    
{/* Campi del modulo */}
); } export default MyForm;

In questo esempio:

Passare lo Stato Durante la Navigazione

È anche possibile passare uno stato insieme alla navigazione utilizzando il secondo argomento di navigate:


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

Ciò consente di passare dati al componente di destinazione, a cui si può accedere utilizzando l'hook useLocation.

4. Route Annidate e Layout

Le route annidate consentono di creare strutture di routing gerarchiche, in cui una route è annidata all'interno di un'altra. Questo è utile per organizzare applicazioni complesse con più livelli di navigazione. Aiuta a creare layout in cui determinati elementi dell'interfaccia utente sono costantemente presenti in una sezione dell'applicazione.

Esempio: Sezione Profilo Utente

Supponiamo di avere una sezione del profilo utente con route annidate per visualizzare le informazioni del profilo, le impostazioni e gli ordini dell'utente:


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

function Profile() {
  return (
    

Profilo Utente

  • Informazioni Profilo
  • Impostazioni
  • Ordini
} /> } /> } />
); } function ProfileInformation() { return

Componente Informazioni Profilo

; } function Settings() { return

Componente Impostazioni

; } function Orders() { return

Componente Ordini

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

In questo esempio:

L'asterisco * nella route genitore è cruciale; significa che la route genitore deve corrispondere a qualsiasi sotto-percorso, permettendo alle route annidate di essere correttamente abbinate all'interno del componente Profile.

5. Gestire gli Errori "Not Found" (404)

È essenziale gestire i casi in cui l'utente naviga verso una route che non esiste. React Router v6 rende questo compito semplice con una route "catch-all" (universale).

Esempio: Implementare una Pagina 404


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

function NotFound() {
  return (
    

404 - Pagina Non Trovata

La pagina che stai cercando non esiste.

Torna alla home
); } function App() { return ( } /> } /> } /> ); }

In questo esempio:

6. Strategie di Caricamento Dati con React Router v6

React Router v6 non include meccanismi di caricamento dati integrati come il suo predecessore (React Router v5 con `useRouteMatch`). Tuttavia, fornisce gli strumenti per implementare efficacemente varie strategie di caricamento dati.

Opzione 1: Recuperare i Dati nei Componenti

L'approccio più semplice è recuperare i dati direttamente all'interno del componente che renderizza la route. Si può usare l'hook useEffect per recuperare i dati quando il componente viene montato o quando i parametri dell'URL cambiano.


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

    fetchProduct();
  }, [productId]);

  if (loading) return 

Caricamento in corso...

; if (error) return

Errore: {error.message}

; if (!product) return

Prodotto non trovato

; return (

{product.name}

{product.description}

); } export default ProductDetails;

Questo approccio è diretto ma può portare a duplicazione del codice se è necessario recuperare dati in più componenti. È anche meno efficiente perché il recupero dei dati inizia solo dopo che il componente è stato montato.

Opzione 2: Usare un Hook Personalizzato per il Recupero Dati

Per ridurre la duplicazione del codice, è possibile creare un hook personalizzato che incapsula la logica di recupero dati. Questo hook può poi essere riutilizzato in più componenti.


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(`Errore HTTP! stato: ${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;

Quindi, è possibile utilizzare questo hook nei propri componenti:


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 

Caricamento in corso...

; if (error) return

Errore: {error.message}

; if (!product) return

Prodotto non trovato

; return (

{product.name}

{product.description}

); } export default ProductDetails;

Opzione 3: Usare una Libreria di Routing con Funzionalità di Recupero Dati (TanStack Router, Remix)

Librerie come TanStack Router e Remix offrono meccanismi di recupero dati integrati che si integrano perfettamente con il routing. Queste librerie spesso forniscono funzionalità come:

L'uso di una tale libreria può semplificare drasticamente il caricamento dei dati e migliorare le prestazioni, specialmente per applicazioni complesse.

Server Side Rendering (SSR) e Static Site Generation (SSG)

Per migliorare la SEO e le prestazioni di caricamento iniziale, considerate l'uso di SSR o SSG con framework come Next.js o Gatsby. Questi framework consentono di recuperare i dati sul server o durante il processo di build e di servire HTML pre-renderizzato al client. Ciò elimina la necessità per il client di recuperare i dati al caricamento iniziale, risultando in un'esperienza più veloce e più SEO-friendly.

7. Lavorare con Diversi Tipi di Router

React Router v6 fornisce diverse implementazioni di router per adattarsi a vari ambienti e casi d'uso:

Scegli il tipo di router che meglio si adatta ai requisiti e all'ambiente della tua applicazione.

Conclusione

React Router v6 offre una soluzione di routing completa e flessibile per le applicazioni React. Comprendendo e applicando i pattern di navigazione discussi in questo articolo, è possibile costruire applicazioni web robuste, facili da usare e manutenibili. Dal routing dichiarativo con <Routes> e <Route> alle route dinamiche con parametri URL, alla navigazione programmatica con useNavigate e alle efficaci strategie di caricamento dati, React Router v6 ti dà il potere di creare esperienze di navigazione fluide per i tuoi utenti. Considera di esplorare librerie di routing avanzate e framework SSR/SSG per un controllo e un'ottimizzazione delle prestazioni ancora maggiori. Ricorda di adattare questi pattern ai requisiti specifici della tua applicazione e di dare sempre la priorità a un'esperienza utente chiara e intuitiva.

React Router v6: Padroneggiare i Pattern di Navigazione per le App Web Moderne | MLOG