Correction services router: double createRoot dans main.jsx (le 2e ecrase et perd BrowserRouter) -> un seul render StrictMode>BrowserRouter>App; + variante BrowserRouter dans main OU App
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# 🔧 Correction — React Router : pourquoi ça plante
|
||||
|
||||
D'abord, une **bonne nouvelle** : avoir `BrowserRouter` dans `main.jsx` **et** `Routes`/`Route` dans `App.jsx`, ce **n'est pas** une erreur — c'est exactement le **bon découpage** :
|
||||
- `main.jsx` **enveloppe** toute l'app dans `<BrowserRouter>` (il « allume » le routeur).
|
||||
- `App.jsx` **déclare les routes** (`<Routes>`/`<Route>`).
|
||||
|
||||
Ton vrai bug est ailleurs. 👇
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Le bug : tu rends ton app **deux fois** dans `main.jsx`
|
||||
|
||||
```jsx
|
||||
createRoot(document.getElementById("root")).render(
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>,
|
||||
);
|
||||
|
||||
createRoot(document.getElementById("root")).render( // ❌ un DEUXIÈME render dans le même #root
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
);
|
||||
```
|
||||
|
||||
Tu appelles `createRoot(...).render(...)` **deux fois** sur le **même** `#root`. Le **second** écrase le premier. Or le second n'a **pas** de `<BrowserRouter>` → ton app finit affichée **sans routeur**.
|
||||
|
||||
Résultat : quand `App` rencontre `<Routes>`, React ne trouve aucun routeur autour → erreur du genre **« useRoutes() may be used only in the context of a `<Router>` »**, et page blanche.
|
||||
|
||||
> 🧠 **À retenir :** il n'y a **qu'un seul** `createRoot(...).render(...)` dans toute l'app — c'est le point d'entrée unique. On n'en met pas deux.
|
||||
|
||||
---
|
||||
|
||||
## ✅ La correction : UN seul `render`, qui imbrique tout
|
||||
|
||||
On garde `StrictMode` **et** `BrowserRouter`, en les **emboîtant** (l'un dans l'autre), avec un seul `render` :
|
||||
|
||||
```jsx
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import "./index.css";
|
||||
import App from "./App.jsx";
|
||||
|
||||
createRoot(document.getElementById("root")).render(
|
||||
<StrictMode>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</StrictMode>,
|
||||
);
|
||||
```
|
||||
|
||||
> 🔎 L'ordre habituel : `StrictMode` (un outil de dev de React) **autour de** `BrowserRouter` **autour de** `App`. Comme des poupées russes.
|
||||
|
||||
**✅ Test :** la page d'accueil (`/`) s'affiche, plus d'erreur de `<Router>`. Va sur une URL `/trilogie/3` → ta page `Details` s'affiche.
|
||||
|
||||
---
|
||||
|
||||
## 💡 Variante : où mettre `<BrowserRouter>` ?
|
||||
|
||||
Les **deux** placements sont corrects, choisis-en **un seul** :
|
||||
|
||||
**Option 1 (celle de l'énoncé) — dans `main.jsx`** (autour de `<App/>`) :
|
||||
```jsx
|
||||
// main.jsx
|
||||
<StrictMode>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</StrictMode>
|
||||
```
|
||||
```jsx
|
||||
// App.jsx
|
||||
function App() {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/" element={<Accueil />} />
|
||||
...
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**Option 2 — dans `App.jsx`** (autour des `<Routes>`) :
|
||||
```jsx
|
||||
// App.jsx
|
||||
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||||
function App() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/" element={<Accueil />} />
|
||||
...
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
```
|
||||
(et dans ce cas, **pas** de `BrowserRouter` dans `main.jsx`.)
|
||||
|
||||
> 🧩 **La seule règle :** il faut **un** `<BrowserRouter>`, et il doit **envelopper** tes `<Routes>`. Que ce soit dans `main.jsx` ou dans `App.jsx`, peu importe — mais **pas les deux**, et jamais deux `BrowserRouter`.
|
||||
|
||||
---
|
||||
|
||||
## 🔎 Vérifie aussi
|
||||
|
||||
Ton `App.jsx` est bon :
|
||||
```jsx
|
||||
<Routes>
|
||||
<Route path="/" element={<Accueil />} />
|
||||
<Route path="/trilogie/:id" element={<Details />} />
|
||||
</Routes>
|
||||
```
|
||||
Assure-toi juste que **`pages/Accueil.jsx` contient bien ta liste** (cartes + recherche + tri + formulaire + total) — c'est elle, maintenant, ta page d'accueil. Si « / » est vide, c'est que le contenu n'a pas été déplacé dans `Accueil`.
|
||||
|
||||
Et dans `Carte`, pour aller vers le détail, utilise un `<Link>` (pas un `<a href>`) :
|
||||
```jsx
|
||||
import { Link } from "react-router-dom";
|
||||
<Link to={`/trilogie/${props.id}`}>Voir les détails</Link>
|
||||
```
|
||||
(il te faudra passer `id` en prop à la `Carte` depuis `Accueil`.)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Récap
|
||||
- [ ] **Un seul** `createRoot(...).render(...)` dans `main.jsx`
|
||||
- [ ] Emboîter `StrictMode > BrowserRouter > App`
|
||||
- [ ] Vérifier que `pages/Accueil.jsx` contient bien ta liste
|
||||
- [ ] `<Link to="/trilogie/:id">` dans les cartes pour naviguer
|
||||
|
||||
> 💬 À garder : `BrowserRouter` (dans `main`) = « j'allume le routeur » ; `Routes`/`Route` (dans `App`) = « voici quelle page pour quelle URL ». Et **un seul** `render`.
|
||||
Reference in New Issue
Block a user