Ta console explose de logs, ton navigateur ralentit, l'onglet freeze — tu es face à une boucle infinie useEffect. C'est le bug React le plus frustrant pour les débutants. Voici les 5 causes et comment les corriger.
Comment détecter une boucle infinie
- Console qui spam : des centaines de logs identiques
-
Erreur React :
Too many re-renders. - Navigateur qui rame : 100% CPU
- Network : dizaines de fetch identiques
Cause 1 : Pas de tableau de dépendances
// ❌ S'exécute à CHAQUE rendu
useEffect(() => {
fetch('/api/data').then(r => r.json()).then(setData);
}); // pas de []
// ✅ Une seule fois au montage
useEffect(() => {
fetch('/api/data').then(r => r.json()).then(setData);
}, []); // tableau vide
Cause 2 : setState avec la valeur dans les deps
// ❌ count change → useEffect → setCount → 💥
const [count, setCount] = useState(0);
useEffect(() => {
setCount(count + 1);
}, [count]);
// ✅ Forme fonctionnelle
useEffect(() => {
const timer = setInterval(() => {
setCount(prev => prev + 1);
}, 1000);
return () => clearInterval(timer);
}, []);
Cause 3 : Objet/array dans les dépendances
// ❌ Nouvel objet à chaque rendu = nouvelle référence
const options = { query, limit: 10 };
useEffect(() => {
fetchResults(options);
}, [options]); // 💥
// ✅ Dépendre des primitives
useEffect(() => {
fetchResults({ query, limit: 10 });
}, [query]); // string = stable
Cause 4 : Fonction qui recrée un objet
// ❌
useEffect(() => {
fetch(\`/api?\${new URLSearchParams(getFilters())}\`);
}, [getFilters()]); // nouvel objet = 💥
// ✅ Constante
const FILTERS = { category: 'tech' };
useEffect(() => {
fetch(\`/api?\${new URLSearchParams(FILTERS)}\`);
}, []);
Cause 5 : Fetch → setState → re-render → fetch
// ❌ url change dans l'effet qui dépend de url
useEffect(() => {
fetch(url).then(r => r.json()).then(result => {
setData(result);
setUrl(result.nextPage); // change url → relance 💥
});
}, [url]);
// ✅ url ne change que sur action utilisateur
useEffect(() => {
fetch(url).then(r => r.json()).then(setData);
}, [url]);
const loadMore = () => setUrl(data.nextPage); // clic
La règle d'or
Si tu peux calculer une valeur sans useEffect, ne l'utilise pas.
// ❌ useEffect pour du state dérivé
useEffect(() => {
setTotal(items.reduce((s, i) => s + i.price, 0));
}, [items]);
// ✅ Calcul direct
const total = items.reduce((s, i) => s + i.price, 0);
Article original sur gogokodo.com
Top comments (0)