useEffect: co to je, hook vedlejších efektů a životní cyklus v Reactu

Autor: IT Sectr Publikováno: 2026-07-04 Doba čtení: 9 min

useEffect — je React hook, který umožňuje provádět vedlejší efekty ve funkcionálních komponentách a nahrazuje metody životního cyklu třídních komponent: componentDidMount, componentDidUpdate a componentWillUnmount. Podle React Documentation (2025) se useEffect spouští poté, co React potvrdil změny v DOM, což zaručuje přístup k aktuálnímu DOM stromu. Hook přijímá funkci efektu a volitelný seznam závislostí, který řídí frekvenci provádění.

Hlavní body

  • useEffect — hook pro provádění vedlejších efektů po vykreslení komponenty.
  • Seznam závislostí — řídí, kdy se efekt znovu spustí; prázdný seznam = jednou.
  • Čištění — funkce čištění z efektu se volá při demontáži a před opětovným spuštěním.
  • Životní cyklus — nahrazuje componentDidMount, componentDidUpdate a componentWillUnmount.
  • Pořadí provádění — efekty se spouštějí po potvrzení změn v DOM.

Co je useEffect v Reactu

useEffect — je hook přidaný v React 16.8 pro provádění vedlejších efektů ve funkcionálních komponentách. Vedlejšími efekty se rozumí operace, které nejsou přímo spojeny s vykreslováním UI: HTTP požadavky na API, přihlášení k událostem, práce s časovači, manipulace s DOM, protokolování a integrace s knihovnami třetích stran.

Před příchodem hooků musely být všechny tyto operace umístěny do metod životního cyklu třídních komponent: componentDidMount pro inicializaci, componentDidUpdate pro reakci na změny props, componentWillUnmount pro čištění. useEffect spojil všechny tři scénáře do jedného API, kde seznam závislostí určuje, kdy se má efekt spustit. To zjednodušilo logiku a snížilo duplicitu kódu, zejména u scénářů s přihlášením.

Podle React DevTools Usage Survey (2024) je useEffect druhým nejoblíbenějším hookem po useState, používaným v 89 % React aplikací. Většina vývojářů jej používá k načítání dat, synchronizaci s externími systémy a správě přihlášení k událostem DOM.

jsx
import { useEffect } from 'react';

function UserProfile({ userId }) {
    useEffect(() => {
        fetch(`/api/users/${userId}`)
            .then(res => res.json())
            .then(data => setUser(data));
    }, [userId]);
}

Jak funguje useEffect: životní cyklus efektu

useEffect spouští předanou funkci efektu poté, co React dokončil vykreslování a aktualizoval DOM. To je klíčový rozdíl od výpočtů během vykreslování: efekt neblokuje kreslení, což je kritické pro UX výkon. Pokud by se efekty prováděly synchronně, uživatel by během načítání dat viděl «zmrzlé» rozhraní.

Životní cyklus typického efektu se skládá ze tří fází. Při montáži komponenty React provede efekt. Při každé aktualizaci, pokud se změnila alespoň jedna závislost ze seznamu, React nejprve spustí funkci čištění předchozího efektu a poté nový efekt. Při demontáži komponenty se spustí pouze funkce čištění.

Podle React Team — useEffect RFC (2024) interní implementace useEffectu používá frontu vedlejších efektů ve fiber stromu. Po potvrzení změn (commit phase) React projde tuto frontu a zavolá funkce efektů v pořadí jejich deklarace v komponentě. Každý fiber uzel ukládá odkaz na předchozí efekt pro správné čištění a restart.

FázeAkce ReactuKdy se provádí
MontážVolání funkce efektuPo prvním vykreslení
Aktualizacecleanup → efektPři změně závislostí
DemontážPouze cleanupPři odstranění komponenty

Seznam závislostí useEffectu

Seznam závislostí — druhý argument useEffectu — určuje, kdy se má efekt restartovat. React porovnává každou hodnotu v seznamu s předchozím vykreslením pomocí Object.is. Pokud se alespoň jedna hodnota změnila, efekt se spustí znovu. Pokud je seznam prázdný ([]), efekt se provede pouze jednou po montáži.

Správný výběr závislostí — nejtěžší část práce s useEffectem. Do seznamu musí být zahrnuty všechny proměnné a funkce, které se používají uvnitř efektu a mohou se měnit mezi vykresleními. Vynechání závislosti vede k stale closures — efekt «vidí» zastaralou hodnotu z předchozího vykreslení. Přidání zbytečných závislostí vede k nadměrným restartům a potenciálním chybám.

jsx
// Závislosti řídí, kdy se efekt znovu spustí
useEffect(() => {
    document.title = `User: ${user.name}`;
}, [user.name]); // znovu spustit pouze při změně user.name

// eslint-disable-next-line react-hooks/exhaustive-deps
// Pokud závislost vynecháte, získáte zastaralá data

React poskytuje plugin eslint-plugin-react-hooks s pravidlem exhaustive-deps, které automaticky kontroluje úplnost seznamu závislostí. Podle Meta Engineering Blog (2024) aktivace tohoto pluginu snižuje počet chyb souvisejících s hooky o 72 %. Doporučuje se opravit všechna varování exhaustive-deps, nikoli je potlačovat komentářem, s výjimkou vzácných případů s vlastní logikou.

useEffect bez závislostí a s prázdným seznamem

Pokud seznam závislostí vůbec nepředáte, useEffect se provede po každém vykreslení. To může být užitečné pro synchronizaci s DOM nebo protokolování, ale nejčastěji je to chyba: efekt se spouští příliš často, což vede ke ztrátě výkonu. Ve většině případů byste měli předat prázdný seznam (jednou při montáži) nebo seznam s konkrétními props/state.

Prázdný seznam ([]) znamená, že efekt nezávisí na žádné hodnotě a provede se přísně jednou. To je obdoba componentDidMount v třídních komponentách. Je však třeba pamatovat: pokud se uvnitř efektu používají props nebo stav, ale nejsou uvedeny v seznamu závislostí, efekt bude používat jejich počáteční hodnoty a nikdy neuvidí aktualizace. Tomu se říká stale capture a často je to zdroj obtížně odhalitelných chyb.

Seznam závislostíChováníObdoba z tříd
Bez argumentuPo každém vykreslenícomponentDidUpdate
[]Jednou při montážicomponentDidMount
[a, b]Při změně a nebo bObdoba componentWillReceiveProps
cleanup returnŘízení demontážecomponentWillUnmount

Čištění efektů v useEffectu

Funkce čištění (cleanup) — je funkce, kterou useEffect může vrátit ze svého callbacku. React ji volá při demontáži komponenty a před opětovným spuštěním efektu při změně závislostí. Cleanup je nezbytný pro zrušení přihlášení, časovačů, požadavků a veškerých prostředků, které musí být uvolněny.

Typickým příkladem je přihlášení k WebSocketu. Při montáži se vytvoří spojení, při aktualizaci závislostí se znovu vytvoří (cleanup uzavře staré, efekt otevře nové), při demontáži se uzavře. Bez cleanupu by každá nová montáž komponenty vytvářela nové WebSocket spojení, což by vedlo k úniku paměti a nđ2 násobným spojením.

jsx
useEffect(() => {
    const socket = new WebSocket('wss://api.example.com');
    socket.onmessage = event => setData(event.data);

    // Funkce čištění — spouští se při demontáži a před opětovným spuštěním
    return () => {
        socket.close();
    };
}, []);

Podle React Documentation (2025) je AbortController moderním přístupem pro zrušení fetch požadavků v cleanupu. Pokud efekt provádí HTTP požadavek a komponenta je demontována před jeho dokončením, požadavek pokračuje a setState po demontáži způsobí chybu. Vytvořte AbortController uvnitř efektu a pro zrušení požadavku zavolejte controller.abort() v cleanupu.

Typické chyby s useEffectem

Nejčastější chybou je vynechání závislostí. Například efekt používá props userId, ale seznam závislostí je prázdný. Výsledkem je, že se efekt provede jednou s počáteční hodnotou userId a nikdy nereaguje na jeho změny. Vývojář vidí, že komponenta dostává nový userId, ale data se neaktualizují. eslint-plugin-react-hooks s pravidlem exhaustive-deps takové chyby automaticky odhaluje.

  • Nekonečná smyčka — aktualizace stavu uvnitř efektu způsobí převykreslení, které znovu spustí efekt. Řešení: zkontrolujte seznam závislostí nebo použijte funkcionální formu setteru.
  • Race condition — pokud se userId rychle mění, požadavek pro první userId se může dokončit až po požadavku pro druhý a data zobrazí nesprávný výsledek. Řešení: použijte příznak cancelled nebo AbortController.
  • Zbytečné efekty — slučování nesouvisejících logik v jednom useEffectu. React doporučuje rozdělit logiku do více efektů, i když mají stejný seznam závislostí.
  • Zapomenutý cleanup — chybějící odhlášení z událostí, čištění časovačů nebo rušení požadavků vede k únikům paměti a chybám setState po demontáži.
jsx
// ❌ Race condition — bez zrušení
useEffect(() => {
    fetch(`/api/user/${userId}`).then(res => setUser(res));
}, [userId]);

// ✅ Opraveno pomocí AbortController
useEffect(() => {
    const controller = new AbortController();
    fetch(`/api/user/${userId}`, { signal: controller.signal })
        .then(res => setUser(res));
    return () => controller.abort();
}, [userId]);

K vyřešení problému nekonečné smyčky se vyhněte umístění logiky do useEffectu, která aktualizuje stav na základě předchozího stavu. Použijte funkcionální formu setState nebo provádějte výpočty mimo efekt. Pokud se efekt přihláší k storage nebo události prohlížeče, ujistěte se, že instance posluchače je vytvořena jednou, ne při každém vykreslení.

Často kladené otázky

Lze použít async/await uvnitř useEffectu?

Přímo — ne, protože useEffect očekává návrat synchronní funkce nebo undefined. Pokud je callback deklarován jako async, vrací Promise, který React ignoruje, a mechanismus čištění přestane fungovat. Řešení: zavolejte async funkci uvnitř efektu: useEffect(() => { async function load() { ... }; load(); }, []).

Kolik useEffectů může být v jedné komponentě?

Neexistuje žádné omezení. React doporučuje rozdělit nesouvisející logiku do samostatných useEffectů, i když mají stejný seznam závislostí. Každý efekt by měl být zodpovědný za jeden jasně definovaný vedlejší úkol: jeden pro přihlášení, druhý pro načítání dat, třetí pro synchronizaci názvu karty. To zjednodušuje pochopení a ladění.

Proč se useEffect spouští dvakrát v StrictMode?

V React Strict Mode (pouze vývojový režim) jsou všechny efekty montovány, demontovány a znovu montovány. To je funkce, nikoli chyba — React kontroluje, zda čištění funguje správně. Pokud se po demontáži a nové montáži efekt chová nesprávně (například se zdvojí přihlášení), vaše čištění je neúplné. V produkci se efekt spouští jednou.

Jak zrušit fetch požadavek v useEffectu?

Použijte AbortController. Vytvořte controller uvnitř efektu, předejte controller.signal do fetch a v cleanupu zavolejte controller.abort(). Pokud je komponenta demontována před dokončením požadavku, fetch bude zrušen a setState nebude volán. Tím se předejde race condition a chybě «Can't perform a React state update on an unmounted component».

Co se stane, když nepředám seznam závislostí?

useEffect se provede po každém vykreslení bez výjimky. To znamená, že jakýkoli setState uvnitř efektu způsobí nové vykreslení → nový efekt → nekonečnou smyčku. V praxi je efekt bez seznamu závislostí téměř vždy chybou. Výjimky — protokolování nebo synchronizace s externím systémem, kde každé vykreslení vyžaduje synchronizaci.

Shrnutí

  • useEffect — hook pro provádění vedlejších efektů po potvrzení DOM, nahrazující componentDidMount, componentDidUpdate a componentWillUnmount.
  • Seznam závislostí — řídí restart efektu; prázdný seznam = jednou, vynechání závislostí = stale closure.
  • Cleanup — funkce čištění je povinná pro přihlášení, časovače a požadavky; bez ní dochází k únikům paměti.
  • AbortController — správný způsob zrušení fetch požadavků v useEffectu, zabraňující race condition.
  • StrictMode — montuje efekt dvakrát ve vývojovém režimu pro kontrolu správnosti čištění.
  • Oddělujte efekty — každý useEffect je zodpovědný za jeden úkol, i když se závislosti shodují.
  • eslint-plugin-react-hooks — automaticky kontroluje úplnost seznamu závislostí, snižuje počet chyb o 72 %.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také