useEffect: mi ez, a mellékhatások hookja és életciklus a React-ben

Szerző: IT Sectr Megjelenés: 2026-07-04 Olvasási idő: 9 perc

useEffect — ez egy React hook, amely lehetővé teszi mellékhatások végrehajtását funkcionális komponensekben, helyettesítve az osztálykomponensek életciklus metódusait: componentDidMount, componentDidUpdate és componentWillUnmount. A React Documentation (2025) szerint a useEffect azután fut le, miután a React megerősítette a DOM változásait, ami garantálja a hozzáférést a jelenlegi DOM-fához. A hook elfogad egy effekt függvényt és egy opcionális függőségi tömböt, amely a végrehajtás gyakoriságát szabályozza.

Főbb pontok

  • useEffect — hook mellékhatások végrehajtására a komponens renderelése után.
  • Függőségi tömb — szabályozza, mikor indul újra az effekt; üres tömb = egyszer.
  • Tisztítás — a cleanup függvény az effektből leválasztáskor és újraindítás előtt hívódik meg.
  • Életciklus — helyettesíti a componentDidMount, componentDidUpdate és componentWillUnmount metódusokat.
  • Végrehajtási sorrend — az effektek a DOM-változások megerősítése után indulnak.

Mi az a useEffect a React-ben

useEffect — ez egy hook, amelyet a React 16.8-ban adtak hozzá mellékhatások végrehajtására funkcionális komponensekben. Mellékhatások alatt azokat a műveleteket értjük, amelyek nem kapcsolódnak közvetlenül a UI rendereléséhez: HTTP kérések API-hoz, eseményekre való feliratkozás, munka időzítőkkel, DOM-manipulációk, naplózás és harmadik féltől származó könyvtárakkal való integráció.

A hookok megjelenése előtt mindezeket a műveleteket az osztálykomponensek életciklus metódusaiba kellett helyezni: componentDidMount inicializáláshoz, componentDidUpdate a props-változásokra való reagáláshoz, componentWillUnmount tisztításhoz. A useEffect mindhárom forgatókönyvet egyetlen API-ban egyesítette, ahol a függőségi tömb határozza meg, mikor kell az effektnek elindulnia. Ez egyszerűsítette a logikát és csökkentette a kód ismétlődését, különösen az előfizetéses forgatókönyvekben.

A React DevTools Usage Survey (2024) szerint a useEffect a második legnépszerűbb hook a useState után, amelyet a React-alkalmazások 89%-ában használnak. A fejlesztők többsége adatok betöltésére, külső rendszerekkel való szinkronizálásra és DOM-eseményekre való feliratkozások kezelésére használja.

jsx
import { useEffect } from 'react';

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

Hogyan működik a useEffect: az effekt életciklusa

useEffect az átadott effekt függvényt azután hajtja végre, miután a React befejezte a renderelést és frissítette a DOM-ot. Ez a legfontosabb különbség a renderelés alatti számításokhoz képest: az effekt nem blokkolja a rajzolást, ami kritikus a UX-teljesítmény szempontjából. Ha az effektek szinkron módon futnának, a felhasználó egy «lefagyott» felüeletet látna az adatok betöltése közben.

Egy tipikus effekt életciklusa három fázisból áll. A komponens csatlakoztatásakor a React végrehajtja az effektet. Minden frissítésnél, ha a tömb legalább egy függősége megváltozott, a React először az előző effekt tisztító függvényét hajtja végre, majd az új effektet. A komponens leválasztásakor csak a tisztító függvény fut le.

A React Team — useEffect RFC (2024) szerint a useEffect belső megvalósítása egy mellékhatás-sort használ a fiber-fában. A változások megerősítése után (commit phase) a React bejárja ezt a sort és meghívja az effekt függvényeket a komponensben történő deklarálásuk sorrendjében. Minden fiber csomópont tárol egy referenciát az előző effektre a helyes tisztítás és újraindítás érdekében.

FázisReact műveleteMikor történik
CsatlakoztatásEffekt függvény meghívásaAz első renderelés után
Frissítéscleanup → effektFüggőségek változásakor
LeválasztásCsak cleanupKomponens eltávolításakor

A useEffect függőségi tömbje

A függőségi tömb — a useEffect második argumentuma — meghatározza, mikor kell az effektet újraindítani. A React az Object.is segítségével hasonlítja össze a tömb minden értékét az előző rendereléssel. Ha legalább egy érték megváltozott, az effekt újra fut. Ha a tömb üres ([]), az effekt csak egyszer fut le a csatlakoztatás után.

A függőségek helyes megválasztása — a useEffect-tel való munka legnehezebb része. A tömbnek tartalmaznia kell minden változót és függvényt, amelyet az effekt belsejében használnak, és a renderelések között változhatnak. Egy függőség kihagyása stale closures-hoz vezet — az effekt egy elavult értéket «lát»” az előző renderelésből. Felesleges függőségek hozzáadása túlzott újraindításokhoz és potenciális hibákhoz vezet.

jsx
// A függőségek szabályozzák, mikor fut újra az effekt
useEffect(() => {
    document.title = `User: ${user.name}`;
}, [user.name]); // csak akkor fusson újra, ha a user.name változik

// eslint-disable-next-line react-hooks/exhaustive-deps
// Ha kihagysz egy függőséget, elavult adatokat kapsz

A React biztosítja az eslint-plugin-react-hooks bővítményt az exhaustive-deps szabállyal, amely automatikusan ellenőrzi a függőségi tömb teljességét. A Meta Engineering Blog (2024) szerint ennek a bővítménynek az aktiválása 72%-kal csökkenti a hookokkal kapcsolatos hibák számát. Javasolt az összes exhaustive-deps figyelmeztetés javítása, nem pedig megjegyzéssel történő elnyomása, kivéve az egyéni logikával rendelkező ritka eseteket.

useEffect függőségek nélkül és üres tömbbel

Ha egyáltalán nem adsz meg függőségi tömböt, a useEffect minden renderelés után lefut. Ez hasznos lehet a DOM-mal való szinkronizáláshoz vagy naplózáshoz, de a legtöbbször hiba: az effekt túl gyakran fut, ami teljesítményvesztéshez vezet. A legtöbb esetben üres tömböt (egyszer a csatlakoztatáskor) vagy konkrét props/state értékekkel rendelkező tömböt kell átadni.

Az üres tömb ([]) azt jelenti, hogy az effekt nem függ egyetlen értéktől sem, és szigorúan egyszer fut le. Ez a componentDidMount analógiája az osztálykomponensekben. Azonban emlékezni kell: ha az effekt belsejében props-ot vagy állapotot használnak, de azok nem szerepelnek a függőségi tömbben, az effekt a kezdeti értékeiket fogja használni, és soha nem látja a frissítéseket. Ezt stale capture-nek hívják, és gyakran nehezen felderíthető hibák forrása.

Függőségi tömbViselkedésAnalógia osztályokból
Argumentum nélkülMinden renderelés utáncomponentDidUpdate
[]Egyszer a csatlakoztatáskorcomponentDidMount
[a, b]Amikor a vagy b változikcomponentWillReceiveProps analógia
cleanup returnLeválasztás kezelésecomponentWillUnmount

Effektek tisztítása a useEffect-ben

A tisztító függvény (cleanup) — egy függvény, amelyet a useEffect visszaadhat a callback-jéből. A React akkor hívja meg, amikor a komponens leválasztásra kerül, és mielőtt az effekt újra futna a függőségek változásakor. A cleanup szükséges az előfizetések, időzítők, kérések és minden olyan erőforrás lemondásához, amelyet fel kell szabadítani.

Tipikus példa — WebSocket-előfizetés. Csatlakoztatáskor létrejőn a kapcsolat, a függőségek frissítésekor újra létrejőn (a cleanup lezárja a régit, az effekt megnyitja az újat), leválasztáskor bezáródik. Cleanup nélkül a komponens minden újracsatlakoztatása új WebSocket-kapcsolatot hozna létre, ami memóriaszivárgáshoz és több kapcsolathoz vezetne.

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

    // Cleanup függvény — fut leválasztáskor és újrafutás előtt
    return () => {
        socket.close();
    };
}, []);

A React Documentation (2025) szerint az AbortController a modern megközelítés a fetch kérések lemondására a cleanup-ban. Ha egy effekt HTTP kérést indít, és a komponens a kérés befejeződése előtt leválasztásra kerül, a kérés tovább fut, és a setState a leválasztás után hibát okoz. Hozz lére egy AbortController-t az effekten belül, és hívd meg a controller.abort()-ot a cleanup-ban a kérés lemondásához.

Gyakori hibák a useEffect-tel

A leggyakoribb hiba — függőségek kihagyása. Például az effekt használja a userId props-t, de a függőségi tömb üres. Ennek eredményeként az effekt egyszer fut le a userId kezdeti értékével, és soha nem reagál a változásaira. A fejlesztő látja, hogy a komponens új userId-t kap, de az adatok nem frissülnek. Az eslint-plugin-react-hooks az exhaustive-deps szabállyal automatikusan felismeri az ilyen hibákat.

  • Végtelen ciklus — a state frissítése az effekten belül újararenderelést okoz, ami újra elindítja az effektet. Megoldás: ellenőrizd a függőségi tömböt, vagy használd a setter funkcionális formáját.
  • Versenyhelyzet (race condition) — ha a userId gyorsan változik, az első userId-ra vonatkozó kérés befejeződhet a második után, és az adatok hibás eredményt mutatnak. Megoldás: használj cancelled zászlót vagy AbortController-t.
  • Felesleges effektek — nem összefüggő logikák egyesítése egyetlen useEffect-ben. A React javasolja a logika több effektre bontását, még akkor is, ha ugyanaz a függőségi tömbjük.
  • Elfelejtett cleanup — az eseményekről való leiratkozás, az időzítők tisztításának vagy a kérések lemondásának elmulasztása memóriaszivárgáshoz és setState hibákhoz vezet a leválasztás után.
jsx
// ❌ Race condition — nincs lemondás
useEffect(() => {
    fetch(`/api/user/${userId}`).then(res => setUser(res));
}, [userId]);

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

A végtelen ciklus problémájának megoldásához kerüld el olyan logika useEffect-be helyezését, amely az előző állapot alapján frissíti az állapotot. Használd a setState funkcionális formáját, vagy végezd el a számításokat az effekten kívül. Ha az effekt feliratkozik storage-ra vagy böngészőeseményre, győződj meg arról, hogy a figyelő példánya egyszer jön létre, ne minden renderelésnél.

Gyakran ismételt kérdések

Használható az async/await a useEffect-en belül?

Közvetlenül — nem, mert a useEffect egy szinkron függvény vagy undefined visszaadását várja. Ha a callback async-ként van deklarálva, az egy Promise-t ad vissza, amelyet a React figyelmen kívül hagy, és a tisztítási mechanizmus leáll. Megoldás: hívd meg az async függvényt az effekten belül: useEffect(() => { async function load() { ... }; load(); }, []).

Hány useEffect lehet egy komponensben?

Nincs korlátozás. A React javasolja a nem összefüggő logikák különálló useEffect-ekre bontását, még akkor is, ha ugyanaz a függőségi tömbjük. Minden effekt egyetlen világosan meghatározott mellékhatás-feladatért feleljen: egyik az előfizetésért, másik az adatok betöltéséért, harmadik a lapfül címének szinkronizálásáért. Ez leegyszerűsíti a megértést és a hibakeresést.

Miért fut kétszer a useEffect StrictMode-ban?

A React Strict Mode-ban (csak fejlesztői módban) minden effekt csatlakoztatásra, leválasztásra és újracsatlakoztatásra kerül. Ez egy funkció, nem hiba — a React ellenőrzi, hogy a tisztítás megfelelően működik-e. Ha a leválasztás és újracsatlakoztatás után az effekt helytelenül viselkedik (például az előfizetések megkettőződnek), a tisztítás nem teljes. Élesben az effekt egyszer fut le.

Hogyan mondjak le egy fetch kérést a useEffect-ben?

Használj AbortController-t. Hozz létre egy controller-t az effekten belül, add át a controller.signal-t a fetch-nek, és a cleanup-ban hívd meg a controller.abort()-ot. Ha a komponens a kérés befejeződése előtt leválasztásra kerül, a fetch lemondásra kerül, és a setState nem hívódik meg. Ez megakadályozza a race condition-t és a «Can't perform a React state update on an unmounted component» hibát.

Mi történik, ha nem adok meg függőségi tömböt?

A useEffect minden renderelés után kivétel nélkül lefut. Ez azt jelenti, hogy bármely setState az effekten belül új renderelést → új effektet → végtelen ciklust okoz. A gyakorlatban egy függőségi tömb nélküli effekt szinte mindig hiba. Kivételek — naplózás vagy külső rendszerrel való szinkronizálás, ahol minden renderelés szinkronizációt igényel.

Összefoglaló

  • useEffect — hook mellékhatások végrehajtására a DOM megerősítése után, helyettesíti a componentDidMount, componentDidUpdate és componentWillUnmount metódusokat.
  • Függőségi tömb — szabályozza az effekt újraindítását; üres tömb = egyszer, kihagyott függőségek = stale closure.
  • Cleanup — a tisztító függvény kötelező az előfizetésekhez, időzítőkhöz és kérésekhez; nélküle memóriaszivárgás történik.
  • AbortController — a fetch kérések lemondásának helyes módja a useEffect-ben, megelőzve a race condition-t.
  • StrictMode — kétszer csatlakoztatja az effektet fejlesztői módban a tisztítás helyességének ellenőrzéséhez.
  • Effektek szétválasztása — minden useEffect egy feladatért felel, még akkor is, ha a függőségek megegyeznek.
  • eslint-plugin-react-hooks — automatikusan ellenőrzi a függőségi tömb teljességét, 72%-kal csökkentve a hibák számát.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is