Stop useEffect mánii! Kdy ho (ne)používat a proč
Čau! Vítej u zpovědi každého (nejen) juniorního React vývojáře.
Naučíš se nový, super výkonný nástroj a najednou... ho vidíš všude. useEffect je přesně takový nástroj. Je to tvůj první švýcarák v Reactu. Chceš fetchnout data? useEffect! Chceš reagovat na změnu props? useEffect! Chceš si uvařit kafe? No... skoro useEffect!
Je to takové to klasické: "Když máš v ruce kladivo, všechno vypadá jako hřebík."
Jenže useEffect je sice kámoš, ale umí být i pěkně zrádný. Může ti zanést do aplikace zbytečné re-rendery, nečekané bugy a kód, který se čte stejně dobře jako egyptské hieroglyfy.
Sami tvůrci Reactu v nové dokumentaci bijí na poplach a říkají: "Hele, lidi, možná ten useEffect vůbec nepotřebujete tak často, jak si myslíte."
Pojďme se podívat, kdy po něm saháš úplně zbytečně a kdy je naopak přesně tím, co potřebuješ.
Hříchy, kterých se (možná) dopouštíš aneb KDY useEffect NEPOUŽÍVAT
1. Hřích: Počítání a filtrování dat pro render
Tohle je klasika. Máš seznam úkolů a chceš zobrazit jen ty, které jsou viditelné podle aktuálního filtru.
Jak to (špatně) děláš teď:
function TodoList({ todos, filter }) {
const [visibleTodos, setVisibleTodos] = useState([]);
// 👎 Když se změní `todos` nebo `filter`, spustí se efekt a nastaví nový stav
useEffect(() => {
setVisibleTodos(todos.filter(t => t.matches(filter)));
}, [todos, filter]);
return (
// ...renderuješ `visibleTodos`
);
}
Vidíš ten problém? Změní se props → spustí se efekt → zavolá se setVisibleTodos → komponenta se znovu přerenderuje. Je to zbytečné kolečko navíc, které zpomaluje aplikaci.
Jak je to správně (a jednodušeji):
function TodoList({ todos, filter }) {
// ✅ Prostě si to spočítej přímo při renderu!
const visibleTodos = todos.filter(t => t.matches(filter));
return (
// ...renderuješ `visibleTodos`
);
}
Žádný useEffect, žádný extra state, žádný zbytečný re-render. Prostě čistý, deklarativní kód. React je dost chytrý na to, aby si tohle pohlídal sám. Pokud je výpočet opravdu náročný (bavíme se o tisících položek), sáhneš po useMemo, ale to je zase jiný příběh.
2. Hřích: Reagování na uživatelské akce
Chceš odeslat notifikaci, když uživatel přidá produkt do košíku.
Jak to (špatně) děláš teď:
function ShoppingCart({ product }) {
const [added, setAdded] = useState(false);
// 👎 Když se `added` změní na `true`, efekt ukáže notifikaci
useEffect(() => {
if (added) {
showNotification(`"${product.name}" byl přidán do košíku!`);
}
}, [added, product.name]);
function handleAddClick() {
setAdded(true);
}
// ...
}
Proč je to špatně? Kód, který patří logicky k sobě (kliknutí na tlačítko a zobrazení notifikace), je rozdělený na dvě místa. Je to nepřehledné a zbytečně komplikované.
Jak je to správně (a logicky):
function ShoppingCart({ product }) {
// ✅ Dej tu logiku tam, kam patří - do event handleru!
function handleAddClick() {
addToCart(product); // nějaká logika pro přidání do košíku
showNotification(`"${product.name}" byl přidán do košíku!`);
}
// ...
}
Jednoduché. Přímé. Čitelné. Uživatel klikne, stane se akce. Hotovo. Event handler je pro věci, které se mají stát v reakci na konkrétní interakci.
OK, tak k čemu ten useEffect sakra je?!
Teď to vypadá, že useEffect je úplně k ničemu, co? Ale kdepak. Má svou naprosto klíčovou a nezastupitelnou roli.
useEffect slouží k synchronizaci s externím systémem.
Co je "externí systém"? Cokoliv, co není pod kontrolou Reactu. Cokoliv, co je "tam venku", mimo tvůj hezký, uzavřený svět komponent, stavů a props.
Tady jsou hlavní případy, kdy je useEffect tvůj nejlepší kámoš:
🌐 Fetchování dat: API na serveru je externí systém. Chceš načíst data, když se komponenta poprvé zobrazí? useEffect s prázdným polem závislostí je tvůj člověk.
📡 Přihlašování k odběrům (Subscriptions): Připojuješ se na WebSocket server, posloucháš na události prohlížeče (window.addEventListener) nebo používáš knihovnu třetí strany, která vyžaduje nějaké subscribe()? To je přesně práce pro useEffect. A hlavně nezapomeň na "cleanup" funkci (to, co vrátíš z efektu), aby ses zase odhlásil!
🎨 Přímá manipulace s DOMem: Potřebuješ napojit nějakou non-React knihovnu na <canvas> nebo animovat prvek způsobem, který React nepodporuje? useEffect a useRef ti podají pomocnou ruku.
📊 Logování a analytika: Chceš poslat informaci do analytického nástroje pokaždé, když se zobrazí určitá stránka? useEffect to zařídí.
Závěrečné moudro
Přestaň vnímat useEffect jako univerzální řešení na všechno. Začni o něm přemýšlet jako o mostu. Mostu mezi tvým čistým, předvídatelným React světem a tím "chaotickým" světem venku.
Pokud tvoje logika neopouští hranice Reactu (jen počítáš věci ze stavu a props nebo reaguješ na kliknutí), pravděpodobně žádný most nepotřebuješ.
A přesně o tomhle způsobu přemýšlení je náš React kurz.
Neučíme tě jen slepě opisovat kód. Učíme tě přemýšlet jako React developer.
Chápat PROČ věci fungují tak, jak fungují.
Chceš se to naučit pořádně? Přestaň se trápit a pojď do toho s námi.
➡️Kurz Reactu

