📋 Rendre des listes avec .map()
Pour afficher une liste d'éléments en React, on utilise .map() pour transformer chaque élément en JSX.
const fruits = ['Pomme', 'Banane', 'Cerise'];
function ListeFruits() {
return (
<ul>
{fruits.map(fruit => (
<li key={fruit}>{fruit}</li>
))}
</ul>
);
}
// Avec des objets
const utilisateurs = [
{ id: 1, nom: 'Alice', role: 'Dev' },
{ id: 2, nom: 'Bob', role: 'Designer' },
];
function ListeUtilisateurs() {
return (
<div>
{utilisateurs.map(u => (
<div key={u.id}>
<strong>{u.nom}</strong> — {u.role}
</div>
))}
</div>
);
}
🔑 La prop key
La key est une prop spéciale que React utilise pour identifier de manière unique chaque élément d'une liste. Elle permet à React de savoir quels éléments ont changé, ont été ajoutés ou supprimés.
// ❌ Sans key — React ne peut pas optimiser les mises à jour
{items.map(item => <Item item={item} />)}
// ❌ Index comme key — problématique si la liste est réordonnée
{items.map((item, i) => <Item key={i} item={item} />)}
// ✅ ID unique stable
{items.map(item => <Item key={item.id} item={item} />)}
// ✅ Valeur unique si pas d'ID
{fruits.map(fruit => <li key={fruit}>{fruit}</li>)}
⚠️ Ne jamais utiliser l'index comme key si les éléments peuvent être réordonnés, ajoutés ou supprimés — cela cause des bugs de rendu difficiles à trouver.
🔍 Filtrer et trier
function ListeProduits({ produits }) {
const [recherche, setRecherche] = useState('');
const [tri, setTri] = useState('nom'); // 'nom' | 'prix'
// Filtrer
const filtres = produits.filter(p =>
p.nom.toLowerCase().includes(recherche.toLowerCase())
);
// Trier (sans muter le tableau)
const tries = [...filtres].sort((a, b) => {
if (tri === 'prix') return a.prix - b.prix;
return a.nom.localeCompare(b.nom);
});
return (
<div>
<input value={recherche} onChange={e => setRecherche(e.target.value)} placeholder="Rechercher..." />
<select value={tri} onChange={e => setTri(e.target.value)}>
<option value="nom">Trier par nom</option>
<option value="prix">Trier par prix</option>
</select>
{tries.map(p => <ProduitCard key={p.id} produit={p} />)}
</div>
);
}
✏️ Listes dynamiques
function ListeDynamique() {
const [items, setItems] = useState([
{ id: 1, texte: 'Premier', done: false },
{ id: 2, texte: 'Deuxième', done: true },
]);
// Ajouter
function ajouter(texte) {
setItems(prev => [...prev, { id: Date.now(), texte, done: false }]);
}
// Modifier (toggle)
function toggleDone(id) {
setItems(prev =>
prev.map(item => item.id === id ? { ...item, done: !item.done } : item)
);
}
// Supprimer
function supprimer(id) {
setItems(prev => prev.filter(item => item.id !== id));
}
// Réordonner (monter)
function monter(id) {
setItems(prev => {
const idx = prev.findIndex(i => i.id === id);
if (idx === 0) return prev;
const nouveau = [...prev];
[nouveau[idx - 1], nouveau[idx]] = [nouveau[idx], nouveau[idx - 1]];
return nouveau;
});
}
}