Liste de tâches qui se souvient
Une liste de tâches sauvegardée dans le navigateur, avec des filtres et un compteur de ce qui reste. Le bon exercice pour enregistrer un tableau d'objets et le relire sans rien casser.
- Enregistrer un tableau avec JSON.stringify
- Relire des données sans planter si elles sont abîmées
- Filtrer l'affichage sans toucher aux données
Pourquoi une liste qui se souvient ? La liste de tâches de base oublie tout au rechargement. Ici, chaque changement est enregistré dans localStorage, et la liste revient telle quelle le lendemain.
localStorage ne garde que du texte : on transforme le tableau en JSON pour l'écrire, et on le relit avec JSON.parse. Si le contenu est abîmé ou absent, on repart d'une liste vide plutôt que de planter.
Les filtres ne modifient jamais les données : ils choisissent seulement ce qu'on affiche.
Pourquoi en JavaScript simple ? Une fonction changer qui modifie, sauvegarde et redessine : un seul chemin pour toutes les actions. Dans la démo, le cadre isolé bloque le stockage, la liste y vit en mémoire.
LA CLÉ ET LA LECTURE
Un JSON abîmé ou absent ne doit pas faire planter la page.
const CLE = 'todo-memoire'; function charger() { try { const v = JSON.parse(localStorage.getItem(CLE)); return Array.isArray(v) ? v : []; } catch { return []; } } let taches = charger(), filtre = 'toutes';UN SEUL CHEMIN POUR CHANGER
Modifier, sauvegarder, redessiner : toujours dans cet ordre.
function changer(modifier) { modifier(); try { localStorage.setItem(CLE, JSON.stringify(taches)); } catch { /* stockage bloqué */ } rendre(); }LES ACTIONS
const ajouter = texte => changer(() => taches.push({ id: Date.now(), texte, fait: false })); const cocher = (id, fait) => changer(() => { taches.find(t => t.id === id).fait = fait; }); const supprimer = id => changer(() => { taches = taches.filter(t => t.id !== id); }); const purger = () => changer(() => { taches = taches.filter(t => !t.fait); });FILTRER À L'AFFICHAGE
Les données restent complètes, seul le rendu choisit.
function visibles() { if (filtre === 'afaire') return taches.filter(t => !t.fait); if (filtre === 'faites') return taches.filter(t => t.fait); return taches; }D'UN ONGLET À L'AUTRE
window.addEventListener('storage', e => { if (e.key === CLE) { taches = charger(); rendre(); } });
PIÈGE 1 : Sauvegarder l'objet directement
Mauvais : localStorage.setItem('taches', taches). On enregistre le texte « [object Object] » et tout est perdu.
Correct : JSON.stringify à l'écriture, JSON.parse à la lecture.
PIÈGE 2 : Faire confiance à ce qu'on relit
Mauvais : JSON.parse sans try. Une ancienne version, une extension ou une modification à la main, et la page reste blanche.
Correct : un try et catch, puis vérifier que c'est bien un tableau avant de s'en servir.
PIÈGE 3 : Filtrer les données
Mauvais : taches = taches.filter(...) quand on clique sur « À faire ». En revenant à « Toutes », les tâches faites ont disparu.
Correct : filtrer une copie au moment de l'affichage, jamais l'état lui-même.
- Une date d'échéance par tâche, et les retards en tête de liste.
- Le glisser-déposer pour réordonner, comme dans le tableau kanban.
- La modification au double clic, avec Échap pour annuler.
- Ajoutez un numéro de version dans ce que vous enregistrez : le jour où le format change, vous saurez convertir les anciennes listes.
- Pour des milliers d'éléments ou des fichiers, passez à IndexedDB, plus adapté que localStorage.
Le tableau vit dans un useState initialisé avec une fonction : useState(charger), pour ne lire qu'une fois.
Un useEffect sur taches écrit dans localStorage à chaque changement.
Le filtre est un autre useState, et la liste visible se calcule au rendu.
Chargement des commentaires…