BaliseTonSite

React Router

Navigue entre les pages sans recharger le navigateur.

8.1Installation

Bashbash
npm install react-router-dom

8.2Setup de base

React Router s'installe autour de ton app avec BrowserRouter, puis tu définis tes routes avec Routes et Route :

TSXtsx
// src/main.tsx
import { BrowserRouter } from 'react-router-dom'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
)

// src/App.tsx
import { Routes, Route } from 'react-router-dom'
import { Home } from './pages/Home'
import { About } from './pages/About'
import { Contact } from './pages/Contact'
import { NotFound } from './pages/NotFound'

function App() {
  return (
    <div>
      <Header />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
        <Route path="*" element={<NotFound />} />  {/* 404 */}
      </Routes>
      <Footer />
    </div>
  )
}

8.3Navigation avec Link et NavLink

N'utilise jamais <a href> pour naviguer dans une app React ! Ça rechargerait la page. Utilise Link ou NavLink :

TSXtsx
import { Link, NavLink } from 'react-router-dom'

function Header() {
  return (
    <nav>
      {/* Link : navigation simple */}
      <Link to="/">Accueil</Link>

      {/* NavLink : ajoute une classe "active" automatiquement */}
      <NavLink
        to="/about"
        className={({ isActive }) => isActive ? "font-bold text-blue-600" : "text-slate-600"}
      >
        À propos
      </NavLink>

      <NavLink to="/contact" className={({ isActive }) => isActive ? "font-bold text-blue-600" : "text-slate-600"}>
        Contact
      </NavLink>
    </nav>
  )
}

8.4Routes dynamiques

Comme les routes dynamiques en Next.js ([slug]), React Router utilise le :parametre :

TSXtsx
// Définition de la route
<Route path="/produit/:id" element={<PageProduit />} />

// Composant : récupère le paramètre
import { useParams } from 'react-router-dom'

function PageProduit() {
  const { id } = useParams<{ id: string }>()

  return <h1>Produit n°{id}</h1>
}

// Navigation vers cette route
<Link to="/produit/42">Voir le produit 42</Link>

8.5Routes imbriquées (Nested Routes)

Comme les layouts dans Next.js, tu peux imbriquer des routes pour partager un layout :

TSXtsx
import { Outlet } from 'react-router-dom'

// Layout partagé pour le dashboard
function DashboardLayout() {
  return (
    <div className="flex">
      <aside>
        <NavLink to="/dashboard">Vue d'ensemble</NavLink>
        <NavLink to="/dashboard/stats">Statistiques</NavLink>
        <NavLink to="/dashboard/settings">Paramètres</NavLink>
      </aside>
      <main>
        <Outlet />  {/* ← Les sous-routes s'affichent ici */}
      </main>
    </div>
  )
}

// Configuration
<Routes>
  <Route path="/dashboard" element={<DashboardLayout />}>
    <Route index element={<DashboardHome />} />
    <Route path="stats" element={<DashboardStats />} />
    <Route path="settings" element={<DashboardSettings />} />
  </Route>
</Routes>

8.6Navigation programmatique

Pour naviguer après une action (soumission de formulaire, login...) :

TSXtsx
import { useNavigate } from 'react-router-dom'

function LoginForm() {
  const navigate = useNavigate()

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    const success = await login(email, password)

    if (success) {
      navigate('/dashboard')           // Redirection
      // navigate('/dashboard', { replace: true })  // Sans retour arrière
    }
  }

  return <form onSubmit={handleSubmit}>...</form>
}

// Accéder aux query params
import { useSearchParams } from 'react-router-dom'

function SearchPage() {
  const [searchParams, setSearchParams] = useSearchParams()
  const query = searchParams.get('q') || ''

  return (
    <input
      value={query}
      onChange={e => setSearchParams({ q: e.target.value })}
    />
    // URL: /search?q=react
  )
}

8.7Route protégée

Pour protéger certaines pages (ex: tableau de bord réservé aux utilisateurs connectés) :

TSXtsx
import { Navigate } from 'react-router-dom'

function ProtectedRoute({ children }: { children: React.ReactNode }) {
  const { user } = useAuth()  // Ton hook d'auth

  if (!user) {
    return <Navigate to="/login" replace />
  }

  return children
}

// Utilisation
<Routes>
  <Route path="/login" element={<LoginPage />} />
  <Route path="/dashboard" element={
    <ProtectedRoute>
      <DashboardPage />
    </ProtectedRoute>
  } />
</Routes>

Verifie tes acquis

3 questions pour valider ce chapitre

1. Quelle est la difference entre Link et NavLink dans React Router ?

Valide et sauvegarde ce chapitre

Ne perds pas le fil de ton apprentissage. Chaque QCM terminé sauvegarde ton score. Crée ton profil gratuitement pour débloquer toutes les évaluations du site et retrouver tes résultats plus tard.

Commencer l'aventure
Déjà membre ?Connecte-toi