useContext — egy React hook, amely funkcionális komponensek számára közvetlen hozzáférést biztosít a createContext segítségével létrehozott kontextus adataihoz. A kontextus a Reactben megoldja a props drilling problémáját — a propsok továbbítását számos köztes komponensen keresztül, amelyek maguk nem használják ezeket az adatokat. A React Documentation (2025) szerint a useContext elfogadja a kontextus objektumot és visszaadja a komponensfában feljebb található legközelebbi Provider által beállított aktuális értéket. Amikor a Providerben lévő érték megváltozik, az összes useContext-et használó komponens automatikusan újratöltődik.
Főbb pontok
useContext — egy hook, amelyet a React 16.8-ban adtak hozzá a többi hookkal együtt, és lehetővé teszi az érték olvasását a React kontextusból. A kontextus egy beépített mechanizmus a Reactben, amelyet adatok komponensfán keresztül történő továbbítására terveztek anélkül, hogy minden szinten kézzel kellene propsokat továbbítani. A useContext helyettesíti a Consumer komponenst a régi Context API-ból, és tömörebbé és olvashatóbbá teszi a kódot.
A kontextus használatának tipikus forgatókönyvei közé tartoznak a dizájn témák (világos/sötét), regionális beállítások és fordítások (i18n), felhasználói hitelesítés, alkalmazás beállítások és bármilyen más globális adat, amelyre számos komponensnek van szüksége különböző egymásba ágyazási szinteken. A React csapat azt ajánlja, hogy a kontextust olyan adatokhoz használd, amelyek globálisak a komponensek részfájához, de nem az egész alkalmazáshoz.
A React Team — Context documentation (2025) szerint a kontextus helytelen használata az egyik fő oka a teljesítményproblémáknak a React alkalmazásokban. A Provider értékének minden változása az összes fogyasztó újratöltését okozza, függetlenül attól, hogy az adatok mely része változott meg. A useMemo-n keresztüli optimalizálás és a kontextusok szétválasztása megoldja ezt a problémát.
import { createContext, useContext } from 'react';
// Kontextus létrehozása alapértelmezett értékkel
const ThemeContext = createContext('világos');
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={`btn-${theme}`}>Click</button>;
}
A kontextus mechanizmusa a Reactben a Provider-Consumer minta segítségével van megvalósítva. A createContext egy objektumot ad vissza két entitással: Provider — a komponens, amely továbbítja az értéket, és maga a kontextus objektum, amelyet a useContext használ. A Provider beépül a komponensfába, és továbbítja az értéket az összes gyermek elem számára, függetlenül az egymásba ágyazás mélységétől.
Amikor a React egy useContext hívással találkozik, felfelé halad a fiber fában, hogy megtalálja a legközelebbi Providert az adott kontextushoz. Ha a Provider megtalálható, az értéke kerül visszaadásra. Ha a Provider nem található, a createContext-nek átadott alapértelmezett érték kerül visszaadásra. Ez a keresés minden betöltésnél megtörténik, de a fiber csomópontok memorizálásának köszönhetően nagyon gyors és nem befolyásolja a teljesítményt.
A React — Context internals (2024) szerint a useContext belső megvalósítása a hookok láncolt listáját használja, hasonlóan a useState-hez. Minden hook tárol egy referenciát a fiber csomóponthoz, ami lehetővé teszi a React számára, hogy gyorsan meghatározza, melyik Provider tartozik az adott kontextushoz. Ha a Provider frissíti az értéket, a React megjelöli az összes fiber csomópontot, amely ezt a kontextust használja, újratöltés céljából.
A Provider komponensek egymásba ágyazhatók, kontextusok hierarchiáját hozva létre. Minden gyermek Provider felülírja a szülő értékét a saját részfájához. Ez akkor hasznos, ha az egyik képernyőn világos téma szükséges, egy egymásba ágyazott modális ablakban pedig sötét. A useContext mindig a fában feljebb található legközelebbi Provider értékét adja vissza.
const UserContext = createContext(null);
const ThemeContext = createContext('világos');
function App() {
return (
<UserContext.Provider value={{ name: 'Alice' }}>
<ThemeContext.Provider value='dark'>
<Profile />
</ThemeContext.Provider>
</UserContext.Provider>
);
}
A createContext(defaultValue) függvény létrehoz egy kontextus objektumot. A defaultValue paraméter akkor használatos, amikor egy komponent meghívja a useContext-et, de a fában feljebb nincs megfelelő Provider. defaultValue nélkül a useContext undefined értéket ad vissza, ami váratlan hibákhoz vezethet. Ajánlott mindig értelmes alapértelmezett értéket vagy null átadni.
Egyéni provider létrehozása gyakori minta a kontextus logikájának enkapszulálásához. Az ilyen provider belső részében tárolódik az állapot (useState vagy useReducer segítségével), és a Provider value propján keresztül elérhető. Ez lehetővé teszi a megvalósítási részletek elrejtését a fogyasztó komponensek elől, és a kontextuskezelési logika egy helyre történő központosítását.
// Egyéni provider állapotkezeléssel
const AuthContext = createContext(null);
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = useCallback(async (email, pass) => {
const u = await loginApi(email, pass);
setUser(u);
}, []);
return (
<AuthContext.Provider value={{ user, login }}>
{children}
</AuthContext.Provider>
);
}
Funkcionális komponensekben a useContext az egyetlen mód a kontextushoz való hozzáférésre. Helyettesíti a régi Context API Consumer komponensét, amely render-prop mintát igényelt: <ThemeContext.Consumer>{value => ...}</ThemeContext.Consumer>. A useContext lineárisabbá és olvashatóbbá teszi a kódot, különösen több kontextus használata esetén egy komponensben.
Több kontextus használata esetén egy komponensben egyszerűen hívd meg a useContext-et többször, minden kontextushoz külön-külön. Minden hívás visszaadja a megfelelő Provider értékét. A hívások sorrendje nem számít, mert minden kontextus független entitás. A React optimalizálja a többszörös hívásokat ugyanazon fiber-referencia rendszeren keresztül.
function Dashboard() {
const { user } = useContext(AuthContext);
const theme = useContext(ThemeContext);
const { locale } = useContext(I18nContext);
return (
<div className={`dashboard-${theme}`}>
<h1>{locale.greeting}, {user.name}</h1>
</div>
);
}
A useContext és a Redux közötti választás az állapotkezelés méretétől és összetettségétől függ. A useContext + useReducer egy könnyű helyettesítője a Redux-nak kis és közepes alkalmazásokhoz. Nem igényel külső könyvtár telepítését, könnyebben megtanulható és a legtöbb feladathoz elegendő. A Redux akkor indokolt, ha szigorú architektúra szükséges middleware-rel, fejlesztői eszközökkel és megváltoztathatatlan frissítésekkel.
A Redux fő előnye a useContext-szel szemben az újratöltések optimalizálása. Alapértelmezés szerint, amikor a Provider értéke megváltozik, az összes kontextus fogyasztó újratöltődik. A Redux a useSelector és a shallowEqual segítségével lehetővé teszi a komponensek számára, hogy csak az állapot bizonyos részeire iratkozzanak fel, ami jelentősen csökkenti az újratöltések számát nagy alkalmazásokban. A kontextus is optimalizálható több kis kontextusra bontással.
| Szempont | useContext | Redux |
|---|---|---|
| Összetettség | Nincs külső függőség | Store és middleware konfigurációt igényel |
| Újratöltések | Minden fogyasztó minden változásnál | Csak az adott slice-ra feliratkozottak |
| DevTools | React DevTools | Redux DevTools time-travel-lel |
| Middleware | Nem támogatott | Redux Thunk, Saga, Observable |
| Mikor válassz | Közepes alkalmazások, 3-5 kontextus | Nagyméretű alkalmazások összetett üzleti logikával |
A Redux maintainers — When to use Redux (2024) szerint a React alkalmazások 70%-a nem igényel Redux-ot. Ha kevesebb mint 50 komponensed van és az állapot nem rendelkezik összetett logikával gyorsítótárral, debounce-szal és mellékhatásokkal — a useContext + useReducer bőven elegendő. A Redux boilerplate-et ad hozzá, és tudatosan kell használni.
A leggyakoribb hiba a value objektum újralétrehozása a Provider minden betöltésekor. Ha a Providernek value={{ user, login }} értéket adsz át, minden Provider betöltéskor új objektum jön létre, ami az összes fogyasztó újratöltését okozza, még akkor is, ha az adatok nem változtak. Megoldás — a value memorizálása useMemo segítségével, vagy külön kontextusok használata a gyakran és ritkán változó adatokhoz.
// ❌ Új objektum minden renderelésnél — az összes fogyasztó újratöltődik
<AuthContext.Provider value={{ user, login }}>{children}</AuthContext.Provider>
// ✅ Memorizált érték — újratöltés csak akkor, amikor a felhasználó vagy a login megváltozik
const authValue = useMemo(() => ({ user, login }), [user, login]);
<AuthContext.Provider value={authValue}>{children}</AuthContext.Provider>
A „nagy kontextus” probléma megoldásához oszd fel a globális állapotot logikai csoportokra: AuthContext, ThemeContext, I18nContext. Minden kontextus a saját területéért felel és függetlenül frissül. Ez egyszerűbb, mint egyetlen gigantikus kontextus optimalizálása useMemo segítségével, és kiszámíthatóbb újratöltési viselkedést biztosít.
Gyakran ismételt kérdések
Igen, ha egy mutátor függvényt adsz át a Provider value-jában. A tipikus minta az állapot tárolása a Providerben és mind az adatok, mind a frissítésükhöz szükséges függvények átadása a useContext segítségével. A gyermek komponensek meghívják ezeket a függvényeket, és az állapotváltozás a Providerben automatikusan frissíti az összes fogyasztót. Ez a Redux alap helyettesítője kis alkalmazásokban.
Egyszerű forgatókönyvek esetén a useContext gyorsabb a store és middleware többletterhelésének hiánya miatt. De gyakori frissítések esetén sok fogyasztóval a Redux nyer, mivel a szelektorai (useSelector) az állapot meghatározott részeire iratkoznak fel, míg a useContext minden változásnál újratölti az összes fogyasztót. Magas frissítési gyakoriságú alkalmazásokhoz (animációk, real-time) a Redux vagy speciális könyvtárak választása javasolt.
Nem. A useContext, mint minden hook, csak funkcionális React komponensen vagy egyéni hookon belül hívható meg. Ha egy szokványos függvényben van szükséged a kontextus értékére (például egy segédprogramban vagy szolgáltatásban), add át paraméterként a komponensből, vagy használj külön modult globális állapottal a Reacten kívül.
A kontextus típusosása TypeScript-ben — a típus megadása a createContext-ben: createContext<AuthContextType | null>(null). Ez garantálja, hogy a useContext(AuthContext) a megfelelő típusú értéket adja vissza. Kényelmes minta egy egyéni useAuth hook létrehozása, amely meghívja a useContext-et, ellenőrzi a null-t, és érthető hibát dob: „useAuth must be used within AuthProvider”.
A leggyakoribb ok, hogy a fogyasztó komponens a megfelelő Provideren kívül található. Ellenőrizd, hogy a Provider beburkolja-e a teljes részfát, amelyben a useContext használatra kerül. A második ok, hogy a Provider egy másik kontextus objektumnak lett átadva: a fejlesztő a createContext hívással hozza létre a kontextust, de a useContext-et egy másik createContext példánnyal használja.
Összefoglaló
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.
Olvassa el is