React Hooks — mik ezek, alapvető hookok és használati szabályok

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

A React Hooks — olyan függvények, amelyek lehetővé teszik a state, effektusok, kontextus és más React-képességek használatát funkcionális komponensekben, osztályok írása nélkül. A React 16.8-ban bevezetett hookok radikálisan megváltoztatták a fejlesztési megközelítést, felváltva az olyan bonyolult mintákat, mint a HOC és a render props. A React, 2024 szerint 15 beépített hook létezik, amelyek lefedik a komponenskezelés összes forgatókönyvét.

Főbb pontok

  • Hookok — függvények a React képességeinek funkcionális komponensekhez kapcsolásához extends Component nélkül.
  • useState — alap hook az állapotkezeléshez, értéket és settert ad vissza.
  • useEffect — mellékhatásokhoz: API kérések, feliratkozások, időzítők, DOM manipulációk.
  • useContext — a React kontextus eléréséhez Consumer burkolók és static contextType nélkül.
  • Hookok szabályai — csak a legfelső szinten és csak funkcionális komponenseken vagy egyéni hookokon belül hívható.

Mik a React Hooks?

A React Hooks — a React-be épített függvények halmaza, amelyek lehetővé teszik a keretrendszer belső mechanizmusaihoz való ‘csatlakozást’ osztályok létrehozása nélkül. A React 16.8 előtt a funkcionális komponensek csak props-okat fogadhattak és JSX-et adhattak vissza — bármilyen összetett logika osztálykomponenst igényelt.

Az osztálykomponensek problémája — a kapcsolódó logika szétválasztása. Az egy entitáshoz tartozó kódot (például WebSocket feliratkozás) kényszerűen szét kellett osztani a componentDidMount, componentDidUpdate és componentWillUnmount között. A hookok ezt megoldják: az összes logika egy useEffect-ben csoportosul.

A második probléma — a logika újrafelhasználása. Az állapotlogika osztálykomponensek közötti újrafelhasználásához HOC (magasabb rendű komponensek) vagy render props alkalmazására volt szükség — mindkét minta extra beágyazást hozott létre a komponensfában. Az egyéni hookok ezt a problémát beágyazás nélkül oldják meg.

useState — állapotkezelés

useState — a legalapvetőbb hook. Elfogad egy kezdeti értéket, és egy tuple-t ad vissza: az aktuális értéket és egy függvényt annak frissítésére. Ellentétben a this.setState-tel az osztályokban, a useState nem egyesíti az objektumokat — az új állapot teljesen felváltja az előzőt az adott useState híváshoz.

js
import React, { useState } from 'react';

function Form() {
  const [text, setText] = useState('');
  const [submitting, setSubmitting] = useState(false);

  async function handleSubmit() {
    setSubmitting(true);
    await fetch('/api/submit', {
      method: 'POST',
      body: JSON.stringify({ text })
    });
    setSubmitting(false);
  }

  return (
    <div>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button onClick={handleSubmit}
        disabled={submitting}>
        {submitting ? 'Saving...' : 'Submit'}
      </button>
    </div>
  );
}

A setState funkcionális formája

A useState setterje elfogadhat egy függvényt, amely megkapja az előző értéket és visszaadja az újat. A funkcionális forma kötelező, ha az új állapot az előzőből számítódik és kötegelt setState hívások lehetségesek — minden hívás a naprakész előző értéket kapja.

useEffect — mellékhatások és életciklus

useEffect — hook mellékhatások végrehajtásához funkcionális komponensekben. Két argumentumot fogad: egy effektfüggvényt és egy függőségi tömböt. A React az effektet minden render után végrehajtja, de függőségek megadásakor — csak ha bármelyik megváltozott.

Egy üres függőségi tömb [] azt jelenti, hogy az effekt egyszer fut le az első render után (analóg a componentDidMount-tal). Egy függvény visszaadása az effektből a cleanup, amely a komponens eltávolításakor (analóg a componentWillUnmount-tal) és az effekt újrafuttatása előtt fut le.

js
import React, { useState, useEffect } from 'react';

function ChatRoom({ roomId }) {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    const socket = new WebSocket(`wss://chat/${roomId}`);

    socket.onmessage = (event) => {
      setMessages(prev => [...prev, JSON.parse(event.data)]);
    };

    // Cleanup - socket bezárása
    return () => socket.close();
  }, [roomId]);

  return <ul>
    {messages.map((msg, i) =>
      <li key={i}>{msg.text}</li>
    )}
  </ul>;
}

A useEffect függőségei — az egyetlen kapcsolat az effekt és a külső világ között. Ha az effektben egy props-ból vagy state-ből származó változót használunk, annak a függőségi tömbben kell lennie. Ennek a szabálynak a figyelmen kívül hagyása az elavult adatokkal (stale closure) kapcsolatos hibák forrása.

useContext — hozzáférés a kontextushoz

useContext — hook a kontextus értékének olvasásához. Elfogadja a React.createContext által létrehozott kontextusobjektumot és visszaadja az aktuális értéket. Ha a kontextus megváltozik, a komponens automatikusan újrarenderelődik az új értékkel.

A useContext megjelenése előtt a kontextus elérése funkcionális komponensekben Context.Consumer-be burkolást igényelt, ami beágyazást hozott létre. useContext teljesen megszünteti a Consumer-t — elég a hook-ot a funkcionális komponens bármely pontján meghívni.

js
import React, { createContext, useContext } from 'react';

const ThemeContext = createContext('világos');

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return <button
    className={`btn btn-${theme}`}
  >
    {theme === 'dark' ? 'moon' : '☀️'}
  </button>;
}

A useContext nem helyettesíti a Redux-ot vagy a globális állapotot. A React a kontextust ritkán változó értékekre ajánlja – téma, nyelv, hitelesítés. Gyakran frissülő adatok esetén minden újrarender újraszámítja a kontextus összes fogyasztóját, ami csökkentheti a teljesítményt.

useReducer — összetett állapotlogika

useReducer — alternatíva a useState-hez összetett frissítési logikával rendelkező állapotokhoz. Elfogad egy reducer függvényt és egy kezdeti állapotot, visszaadja az aktuális állapotot és egy dispatch függvényt. A reducer megkapja az aktuális állapotot és az akciót, visszaadja az új állapotot — egy tiszta függvény mellékhatások nélkül.

A useReducer különösen akkor hasznos, ha több akció (set, reset, increment, addItem) kezel egy állapotot. Több useState helyett különböző setterekkel — egy reducer tiszta akciótípusokkal. Ez kiszámíthatóvá és könnyen tesztelhetővé teszi a logikát.

js
import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { ...state, count: state.count + 1 };
    case 'setStep':
      return { ...state, step: action.step };
    case 'reset':
      return { count: 0, step: 1 };
    default:
      throw new Error('Unknown action: ' + action.type);
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, {
    count: 0,
    step: 1
  });

  return (
    <>
      <p>Count: {state.count}</p>
      <button
        onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button
        onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </>
  );
}

useRef, useMemo, useCallback — optimalizálás

useRef létrehoz egy változtatható objektumot, amely megmarad a renderek között. A current módosítása nem okoz újrarenderelést. Fő alkalmazás — hozzáférés DOM elemekhez és változtatható értékek tárolása (időzítők, előző értékek, könyvtárpéldányok).

useMemo memóizálja egy függvény eredményét. Csak akkor számítja újra az értéket, ha az egyik függőség megváltozik. Használja költséges számításokhoz — nagy tömbök szűrése, rendezés, adatok formázása. useCallback — a useMemo speciális esete függvények memóizálásához.

js
import React, { useRef, useMemo, useCallback } from 'react';

function SearchPage({ items, query, onItemSelect }) {
  const inputRef = useRef(null);

  // Autofókusz mountoláskor
  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  // Szűrt eredmény memóizálása
  const filtered = useMemo(() => {
    return items.filter(item =>
      item.name.toLowerCase()
        .includes(query.toLowerCase())
    );
  }, [items, query]);

  // Callback memóizálása
  const handleSelect = useCallback((id) => {
    onItemSelect(id);
  }, [onItemSelect]);

  return (
    <div>
      <input ref={inputRef}
        value={query}
        onChange={e => setQuery(e.target.value)}
      />
      <ul>
        {filtered.map(item =>
          <li key={item.id}>
            <button
              onClick={() => handleSelect(item.id)}>
              {item.name}
            </button>
          </li>
        )}
      </ul>
    </div>
  );
}

Fontos szabály: a useRef, useMemo és useCallback — optimalizálási eszközök, nem kötelező szerkezetek. Ne csomagoljon be mindent useMemo-ba — először mérje meg a teljesítményt. Az idő előtti optimalizálás bonyolítja a kódot. A React gyorsan rendereli a komponenseket; a useMemo csak akkor szükséges, ha a számítások valóban költségesek (O(n²) és magasabb).

Hookok szabályai és gyakori hibák

A React két szigorú szabályt vezetett be a hookok számára. Első: a hookokat csak a legfelső szinten hívja — nem feltételekben, ciklusokban vagy beágyazott függvényekben. Második: a hookokat csak React funkcionális komponensekből vagy egyéni hookokból hívja. Az ESLint bővítmény eslint-plugin-react-hooks automatikusan ellenőrzi mindkét szabályt.

A leggyakoribb hiba — a hookok hívási sorrendjének megsértése. A React a hookok hívási sorrendjére támaszkodik a renderek között. Ha egy hook egy feltételben található és nem hívódott meg az egyik renderben, az összes későbbi hook eltolódik, hibákat okozva.

HibaMi történikMegoldás
Hook feltételbenA hookok sorrendje megtörikHelyezze át a feltétellogikát a hook belsejébe
Stale closureAz effekt régi értéket használAdja hozzá az összes függőséget a tömbhöz
Végtelen ciklusA useEffect függőségek nélkül módosítja a state-etAdja meg a függőségeket vagy használjon useReducer-t
Ref módosítása renderbenMellékhatás a függvény törzsébenHelyezze át a mutációkat a useEffect-be

A második gyakori hiba — stale closure a useEffect-ben. Ha az effektben olyan változót használnak, amely nincs megadva a függőségekben, az effekt ‘elkapja’ annak értékét a lezárás létrehozásának pillanatában. Megoldás — mindig vegye fel az összes használt változót a függőségi tömbbe. Ha túl sok a függőség, ossza fel az effektet több részre.

Gyakran Ismételt Kérdések

Miért nem lehet a hookokat feltételekben hívni?

A React a hookok hívási sorrendjére támaszkodik a renderek között. Ha egy hookot feltételben hívtak, és az nem futott le az egyik renderben, az összes későbbi hook ‘elcsúszik’ — az állapotuk összekeveredik. Az ESLint szabály hooks/exhaustive-deps figyelmeztet erre.

Mi a különbség a useEffect és a useLayoutEffect között?

useLayoutEffect szinkron és a böngésző általi rajzolás előtt fut le. useEffect aszinkron — a rajzolás után. Használja a useLayoutEffect-et csak akkor, ha a DOM-ot a felhasználó általi látás előtt kell mérni vagy módosítani (popover pozíció, scroll helyreállítás).

Hogyan szakítható meg egy fetch kérés a komponens eltávolításakor?

Használjon AbortController-t a useEffect-en belül. Hozzon létre egy controllert, adja át a signal-t a fetch-nek, és a cleanup függvényben hívja meg a controller.abort()-ot. Régebbi böngészőkhöz elegendő egy cancelled zászló: return () => { cancelled = true; } ellenőrzéssel a setState előtt.

Mi az egyéni hook és mikor hozzuk létre?

Egyéni hook — egy JavaScript függvény use előtaggal, amely beépített hookokat használ. Akkor hozza létre, ha ugyanaz a logika hookokkal két vagy több komponensben ismétlődik. Példák: useDebounce, useLocalStorage, useMediaQuery. Az egyéni hookok helyettesítik a HOC-ot és a render props-ot.

Miért fut le a useEffect kétszer Strict Mode-ban?

Strict Mode-ban a React szándékosan kétszer mountolja és unmountolja a komponenst fejlesztési módban, hogy megtalálja a nem tisztított effektusokkal kapcsolatos hibákat. Ha a cleanup helyesen van megírva, a dupla hívás nem okoz problémát. Éles módban ez nem történik meg.

Összefoglaló

  • React Hooks — függvények a state, effektusok és kontextus használatához funkcionális komponensekben, amelyek felváltották az osztályokat.
  • useState — alap hook a lokális állapothoz funkcionális setterrel a biztonságos frissítésekhez.
  • useEffect — univerzális hook mellékhatásokhoz függőségi tömbbel és cleanup függvénnyel.
  • useContext — közvetlen hozzáférés a React kontextushoz Consumer burkolók és extra beágyazás nélkül.
  • useReducer — összetett állapotlogikához akciótípusokkal, Redux alternatíva egy komponensen belül.
  • useRef, useMemo, useCallback — optimalizálási eszközök: DOM referenciák, értékek és callbackek memóizálása.
  • Legfelső szint szabálya — szigorú korlátozás a hookok feltételeken, ciklusokon és beágyazott függvényeken kívüli hívására.

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