# 💾 Énoncé — Sauvegarder les JEUX (pas que les likes) Aujourd'hui, tes **likes** survivent au refresh (bravo, c'est exactement le bon réflexe `localStorage`). Mais la **liste des jeux**, elle, repart du `zelda.json` à chaque rechargement : tes ajouts disparaissent, et tu ne peux ni supprimer ni modifier durablement. Objectif : faire vivre la liste `jeux` **comme** les likes — initialisée depuis `localStorage`, sauvegardée à chaque changement — pour pouvoir **ajouter, supprimer, modifier** et tout retrouver après un F5. > ⚠️ On ne touche à rien d'autre que `App.jsx`, `Accueil.jsx` et `Carte.jsx`. Tu connais déjà toutes les briques : la seule **idée neuve** est « d'où viennent les jeux la première fois ? ». --- ## 🧠 Le seul piège à comprendre d'abord Pour les likes c'était simple : au tout début ils valent `{}`. ```jsx const [likes] = useState(() => JSON.parse(localStorage.getItem("likes") || "{}")); ``` Pour les jeux, c'est différent : la **première fois**, ils ne viennent pas de `localStorage` (vide) mais du **`fetch` du `zelda.json`**. Donc la logique est : > **Si `localStorage` contient déjà des jeux → on les prend. Sinon (première visite) → on va chercher le `zelda.json`.** Une fois chargés, `localStorage` devient **la source de vérité** : c'est lui qu'on relit aux prochains refresh (avec tes ajouts/suppressions/modifs), et le `json` ne ressert plus. --- ## 📝 Étape 1 — Initialiser `jeux` depuis `localStorage` (dans `App.jsx`) Remplace ton `useState([])` par une initialisation paresseuse, avec une **sentinelle `null`** qui veut dire « pas encore chargé » : ```jsx const [jeux, setJeux] = useState(() => { const stocke = localStorage.getItem("jeux"); return stocke ? JSON.parse(stocke) : null; // null = jamais chargé }); ``` > 🔎 Pourquoi `null` et pas `[]` ? Parce qu'on doit **distinguer** deux cas : « la liste est vide parce que tu as tout supprimé » (`[]`, à garder !) et « on n'a encore rien chargé » (`null`, il faut aller chercher le json). Avec `[]` partout, impossible de faire la différence. ## 📝 Étape 2 — Aller chercher le json UNE SEULE FOIS si besoin Ton `useEffect` de fetch existe déjà. Ajoute juste la condition « seulement si rien n'est encore chargé » : ```jsx useEffect(() => { if (jeux === null) { // rien en localStorage → 1re visite fetch("/zelda.json") .then((r) => r.json()) .then(setJeux); } }, []); // [] : on ne tente ça qu'au montage ``` ## 📝 Étape 3 — Sauvegarder à chaque changement Exactement le même réflexe que pour les likes, mais on **ne sauvegarde pas** tant que c'est `null` (sinon on écrirait « null » par-dessus tes données) : ```jsx useEffect(() => { if (jeux !== null) { localStorage.setItem("jeux", JSON.stringify(jeux)); } }, [jeux]); ``` ## 📝 Étape 4 — Gérer l'écran « en cours de chargement » Tant que `jeux` vaut `null`, `Accueil` ne peut pas faire `jeux.length` ou `jeux.map` (ça planterait). Affiche un petit message le temps du fetch. Dans `App.jsx`, juste avant le `return` des routes : ```jsx if (jeux === null) return

Chargement…

; ``` **✅ Test de l'étape 1-4 :** recharge la page → tout s'affiche normalement. Ouvre les outils dev (F12) → *Application → Local Storage* → tu dois voir une clé **`jeux`** avec tous tes jeux dedans. 🎉 --- ## ➕ Étape 5 — Ajouter (ça marche déjà… et maintenant ça PERSISTE) Ta fonction `ajouter` fait déjà `setJeux([...jeux, nouveau])`. Tu n'as **rien à changer** : comme `setJeux` déclenche le `useEffect` de l'étape 3, l'ajout est **automatiquement** sauvegardé. **✅ Test :** ajoute un jeu → F5 → il est **toujours là**. > 🛠️ Détail : ton formulaire crée `Type: "3d"` en dur. Tu peux ajouter un `` qui apparaît dans la carte quand on clique « modifier » (un état `enEdition` qui retient l'id en cours d'édition), et un bouton « Valider ». Plus joli, mais commence par la version `prompt`. **✅ Test :** renomme un jeu → F5 → le nouveau nom est **conservé** (et la page Détail l'affiche aussi). --- ## 🧯 Le bouton « réinitialiser » (très utile pour debugger) Quand on bricole `localStorage`, on aime pouvoir tout remettre à zéro. Un petit bouton : ```jsx ``` Il efface la clé `jeux` → au rechargement, `localStorage` est vide → on repart du `zelda.json` (retour à l'étape 2). --- ## ✅ Checklist - [ ] 1-4 — `jeux` initialisé depuis `localStorage` (sentinelle `null`), fetch **une seule fois**, sauvegarde à chaque changement, écran « Chargement… » - [ ] 5 — ajout persistant (rien à changer, ça marche tout seul) - [ ] 6 — suppression (`filter` + bouton sur la carte) - [ ] 7 — modification (`map` + `prompt`, puis version `` en bonus) - [ ] bonus — bouton « réinitialiser » ## 🧠 Concepts Persistance d'une **liste entière** dans `localStorage` · réconcilier **fetch (1re fois)** vs **localStorage (ensuite)** avec une sentinelle `null` · `filter` (supprimer) et `map` (modifier) **immuables** · une fonction d'`App` passée en props jusqu'à `Carte` pour agir sur la source de vérité. > 🔁 Et si tu veux ranger tout ça proprement : le **custom hook `useLocalStorage`** de l'énoncé final fait exactement ce schéma « état + sauvegarde auto ». Une fois la persistance comprise ici, tu pourras remplacer tes blocs `useState`/`useEffect` par `const [jeux, setJeux] = useLocalStorage("jeux", null)`.