useState: mi ez, state hook és szintaxis React-ben

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

useState — egy beépített React hook, amely lehetővé teszi a funkcionális komponensek számára, hogy osztálykomponensekké alakítás nélkül kezeljék a lokális állapotot. A React 16.8 bevezette a hook-okat, és a useState lett a leggyakrabban használt ezek közül, felváltva a this.state és this.setState osztály alapú megközelítést. A React Documentation (2025) szerint a modern React alkalmazások komponenseinek több mint 80%-a használja a useState-t űrlapadatok, interfész jelzők és számlálók kezelésére. A hook egy tuple-t ad vissza a jelenlegi értékből és egy setter függvényből, amely frissíti az állapotot és elindítja a komponens újrarenderelését.

Főbb pontok

  • useState — hook a lokális állapot kezelésére funkcionális React komponensekben.
  • Tuple — egy [érték, setter] párost ad vissza, ahol a setter az állapotfrissítő függvény.
  • Újrarenderelés — a setter hívása mindig elindítja a komponens újrarajzolását az új értékkel.
  • Adattípusok — a useState számokkal, karakterláncokkal, tömbökkel, objektumokkal és logikai értékekkel működik.
  • Változtathatatlanság — az állapot nem mutálható közvetlenül, csak a setter függvényen keresztül.

Mi az a useState React-ben

useState — a React alapvető hook-ja, amely a 16.8 verzióban került hozzáadásra, és lehetővé teszi a funkcionális komponensek számára a lokális állapot tárolását és módosítását. A hook-ok megjelenése előtt az állapot csak osztálykomponensekben volt használható a this.state és this.setState segítségével, ami a funkcionális komponenseket kizárólag prezentációs célokra tette alkalmassá. A useState megszüntette ezt a korlátozást, lehetővé téve a teljes alkalmazás funkcionális komponensekkel történő megírását.

A hook egy argumentumot fogad — az állapot kezdeti értékét — és egy két elemből álló tömböt ad vissza. Az első elem az állapot jelenlegi értéke, a második a függvény annak frissítésére. A React garantálja, hogy a setter függvény stabil és nem változik a renderelések között, ami lehetővé teszi annak biztonságos átadását gyermekkomponenseknek és használatát closure-ökben.

A React DevTools Usage Survey (2024) szerint a useState a React alkalmazások 96%-ában használatos, így ez a legelterjedtebb hook az ökoszisztémában. Még a Redux vagy Zustand segítségével globális állapotot használó alkalmazásokban is a useState-en keresztüli lokális state marad a UI állapot kezelésének fő mechanizmusa — nyitott modálok, beviteli mezők értékei, aktív lapok.

jsx
import { useState } from 'react';

function Counter() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={() => setCount(count + 1)}>
                Increment
            </button>
        </div>
    );
}

Hogyan működik a useState

A useState belső mechanizmusa a React fiber csomópontrendszerén alapul. A React-ben minden komponenst egy fiber csomópont képvisel, amely a hozzá kapcsolódó hook-ok listáját láncolt lista formájában tárolja. Amikor a komponens meghívja a useState-t, a React létrehoz egy új csomópontot ebben a listában, és eltárolja benne az állapot aktuális értékét és egy hivatkozást a frissítési sorra.

A setter függvény meghívásakor a React nem frissíti azonnal az állapotot. Ehelyett a frissítést egy sorba helyezi (pending state queue), ütemezi a komponens újrarenderelését, és csak a következő renderelés során számítja ki az új állapotot a régi és az alkalmazott frissítések alapján. Ez biztosítja a batch feldolgozást — ha egy eseménykezelőben háromszor hívod meg a setter-t, a React egyetlen újrarenderelésbe csoportosítja azokat.

A React Team — React 18 Working Group (2024) szerint az automatikus batch feldolgozás kibővült a React 18-ban: mostantól az állapotfrissítések nem csak eseménykezelőkben, hanem setTimeout, Promise callback-ekben és natív kezelőkben is csoportosításra kerülnek. Ez akár 30%-os teljesítménynövekedést eredményezett a többszörös állapotfrissítési forgatókönyvekben.

Az állapot funkcionális frissítése

Amikor az új állapot függ az előzőtől, használd a setter funkcionális formáját: setCount(prev => prev + 1). A React a függvénynek a frissítés alkalmazásának pillanatában érvényes állapotértéket adja át, ami garantálja a helyességet még a batch-elt frissítések esetén is. Funkcionális forma nélkül a setCount(count + 1) elavult értéket használhat, ha többször egymás után hívják meg.

jsx
// Lusta inicializálás — csak egyszer fut le
setCount(prev => prev + 1);
setCount(prev => prev + 1);
setCount(prev => prev + 1);
// Result: count increased by 3

// NOT batch-safe: stale closure
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
// Result: count increased by 1 (stale closure)

A useState szintaxisa: deklarálás és frissítés

A useState alap szintaxisa rendkívül tömör: const [state, setState] = useState(initialValue). A kezdeti érték csak az első rendereléskor használatos; a következő rendereléseknél a React figyelmen kívül hagyja és a jelenleg tárolt értéket adja vissza. Ha a kezdeti számítás költséges műveleteket igényel, adj meg egy inicializáló függvényt: useState(() => computeExpensiveInitial()).

A lusta inicializálás (lazy initial state) különösen fontos, ha a kezdeti érték localStorage-ból, összetett adatátalakításból vagy URL paraméterek feldolgozásából származik. A React az inicializáló függvényt csak egyszer hívja meg — a komponens csatlakoztatásakor, ami erőforrásokat takarít meg a későbbi rendereléseknél. Lusta inicializálás nélkül a költséges kifejezés minden rendereléskor kiértékelésre kerül, még akkor is, ha az eredményét figyelmen kívül hagyják.

FormaPéldaMikor használjuk
KözvetlenuseState(0)Egyszerű kezdeti érték
LustauseState(() => compute())Költséges kezdeti számítás
Funkcionális settersetState(prev => prev + 1)Frissítés az előző alapján
Közvetlen settersetState(newValue)Az új érték nem függ a régitől
jsx
// Objektum állapot — hozz létre új referenciát
const [user, setUser] = useState(() => {
    const saved = localStorage.getItem('user');
    return saved ? JSON.parse(saved) : null;
});

useState különböző adattípusokkal

A useState egyaránt jól működik primitívekkel (számok, karakterláncok, logikai értékek) és referencia típusokkal (tömbök, objektumok). Van azonban egy fontos különbség: primitívek esetén a React a változást érték alapján, objektumok és tömbök esetén pedig referencia alapján érzékeli. Egy meglévő objektum mutációja új létrehozása nélkül nem vált ki újrarenderelést, mert a referencia változatlan maradt.

Objektumokkal és tömbökkel való munka során mindig készíts új másolatot a módosított adatokkal. Objektumokhoz használd a spread szintaxist: setUser(prev => ({...prev, name: newName})). Tömbökhöz — olyan metódusokat, amelyek új tömböt adnak vissza: filter, map, concat, vagy a spread szintaxist elemek hozzáadásához. A mutációs metódusok, mint a push, pop, splice közvetlenül nem fognak működni — a React figyelmen kívül hagyja őket, mert a hivatkozás a tömbhöz nem változott.

jsx
// ✅ Helyes: hook-ok a legfelső szinten
const [form, setForm] = useState({ name: '', email: '' });
const updateField = (field, value) =>
    setForm(prev => ({ ...prev, [field]: value }));

// ...
const [items, setItems] = useState([]);
const addItem = item =>
    setItems(prev => [item, ...prev]);

A hook-ok használatának szabályai useState-tel

Mint minden React hook, a useState is két szabályt követ. Először is: a hook-okat csak a komponens legfelső szintjén hívd — nem helyezhetők el feltételekben, ciklusokban vagy beágyazott függvényekben. Ez garantálja, hogy a hook-ok minden rendereléskor ugyanabban a sorrendben kerülnek meghívásra, ami kritikus a React belső láncolt listája számára.

Második szabály: a hook-okat csak funkcionális React komponensekből vagy egyedi hook-okból hívd. Ne hívd a useState-t közönséges függvényekből, callback-ekből vagy osztálykomponensekből. E szabályok megsértése Invalid hook call hibához vezet, amelyet a React a végrehajtás során észlel.

  • Ne feltételekben — if (flag) { useState(0) } megsérti a hook-ok hívási sorrendjét.
  • Ne ciklusokban — for (...) { useState(0) } kiszámíthatatlanná teszi a sorrendet.
  • Ne callback-ekben — useEffect(() => { useState(0) }, []) tönkreteszi a láncolt listát.
jsx
// ❌ Elavult closure probléma
function GoodComponent() {
    const [count, setCount] = useState(0);
    const [name, setName] = useState('');
    // ✅ Javítva funkcionális frissítéssel
}

// a számláló elavult!
function BadComponent() {
    if (isLogged) {
        const [user, setUser] = useState(null);
    }
}

Gyakori hibák a useState-tel

A leggyakoribb hiba — objektumok és tömbök közvetlen mutációja új referenciák létrehozása helyett. A fejlesztők hozzászoktak a mutábilis stílushoz az osztálykomponensekből, ahol a this.state.user.name = „Új név” működött (bár ott sem volt ajánlott). Funkcionális komponensekben az ilyen mutáció egyszerűen figyelmen kívül marad: a React nem látja a referencia változását és nem rajzolja újra a komponenst.

  • Objektum mutációja — user.name = „Új” a setUser({...user, name: „Új”}) helyett.
  • Elavult closure — elavult érték használata a setter-ben funkcionális forma nélkül.
  • Szükségtelen újrarenderelések — a setter meghívása ugyanazzal az értékkel (a React 18 primitíveknél akkor is renderel).
  • Állapot visszaállítása — a komponens key prop-jának véletlen frissítése, ami újra csatlakoztatja azt.

Az elavult closure (stale closure) problémája akkor merül fel, amikor egy useEffect-nek vagy eseménykezelőnek átadott callback „elkapja” az állapot elavult értékét a closure-ből a callback létrehozásának pillanatában. Megoldás — a setter funkcionális formájának használata vagy a szükséges értékek belefoglalása a useEffect függőségi tömbjébe. A React Documentation — Hooks FAQ (2025) szerint az elavult closure-ök a második leggyakoribb okai a hook-okkal kapcsolatos hibáknak a helytelen függőségi tömb után.

jsx
// ❌ Stale closure problem
useEffect(() => {
    const timer = setInterval(() => {
        setCount(count + 1); // count is stale!
    }, 1000);
    return () => clearInterval(timer);
}, []);

// ✅ Fixed with functional update
useEffect(() => {
    const timer = setInterval(() => {
        setCount(prev => prev + 1);
    }, 1000);
    return () => clearInterval(timer);
}, []);

Gyakran Ismételt Kérdések

Használható a useState összetett beágyazott objektumokhoz?

Igen, de óvatossággal. Mélyen beágyazott objektumok esetén minden szint másolást igényel a frissítés során: setState(prev => ({...prev, nested: {...prev.nested, key: newValue}})). Ha három vagy több beágyazási szinttel rendelkező objektumaid vannak, fontold meg az Immer (változtathatatlan frissítés könyvtár) használatát, vagy oszd fel az állapotot több useState-re különböző szintekhez.

A useState aszinkron vagy szinkron?

A useState abban az értelemben aszinkron, hogy a setter meghívása nem frissíti azonnal az értéket. A React a frissítést sorba helyezi és a következő renderelés során hajtja végre. A setCount(newValue) után a count változó a jelenlegi függvényben még mindig a régi értéket tartalmazza. Az új érték csak a komponens következő meghívásakor lesz elérhető.

Mi történik, ha a useState-t a komponensen kívül hívják?

A React Invalid hook call hibát dob. A hook-ok csak funkcionális React komponenseken vagy egyedi hook-okon belül hívhatók (olyan függvények, amelyek neve use-val kezdődik). Ez a korlátozás a hook-ok implementációjába van beépítve: a komponens fiber fáját használják az állapot tárolására, és a komponensen kívül ez a fa nem érhető el.

Mikor használjunk useState-t és mikor useReducer-t?

A useState egyszerű független állapotokhoz alkalmas (számlálók, beviteli mezők, jelzők). A useReducer jobb, ha az állapot egy összetett objektum több mezővel, a frissítési logika függ a művelet típusától, vagy a következő állapot összetett átalakítást igényel. Gyakorlati szabály: ha háromnál több összefüggő állapotmeződ van — használj useReducer-t.

Miért nem frissíti a useState azonnal az értéket?

Ez a teljesítmény érdekében történik. Ha a useState szinkron módon frissítené az állapotot, minden setter hívás azonnali újrarenderelést okozna, ami többszörös újrarajzoláshoz vezetne egy eseménykezelőn belül. A batch feldolgozás, ahol a React csoportosítja a frissítéseket és egyetlen újrarenderelést hajt végre, egy optimalizálás, amelyet már a React 16-ban bevezettek, és jelentősen továbbfejlesztettek a React 18-ban az automatikus batch feldolgozással.

Összefoglalás

  • useState — alapvető React hook a lokális állapot kezelésére funkcionális komponensekben, [state, setter] visszaadásával.
  • Változtathatatlanság — az állapot nem mutálható közvetlenül; mindig adj át új értéket vagy használd a setter funkcionális formáját.
  • Lusta inicializálás — költséges kezdeti számításokhoz adj át függvényt: useState(() => compute()).
  • Funkcionális setter — a setState(prev => prev + 1) garantálja a helyességet batch-elt frissítéseknél.
  • Batch feldolgozás — a React több setter hívást csoportosít egy újrarenderelésbe az optimalizálás érdekében.
  • Hook szabályok — a useState-t csak a komponens legfelső szintjén hívd, nem feltételekben vagy ciklusokban.
  • Adattípusok — objektumok és tömbök esetén mindig hozz létre új referenciát a frissítéskor.

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