useContext — är en React-hook som ger funktionella komponenter direkt åtkomst till data från kontexten som skapats via createContext. Kontext i React löser problemet med props drilling — att skicka props genom flera mellanliggande komponenter som själva inte använder dessa data. Enligt React Documentation (2025), tar useContext emot kontextobjektet och returnerar det aktuella värdet som satts av den närmaste Providern högre upp i komponentträdet. När värdet i Providern ändras, renderas alla komponenter som använder useContext om automatiskt.
Huvudpunkter
useContext — är en hook som lades till i React 16.8 tillsammans med de andra hooks, som låter dig läsa ett värde från React-kontexten. Kontext är en inbyggd mekanism i React, avsedd för att överföra data genom komponentträdet utan att manuellt behöva skicka props på varje nivå. useContext ersätter Consumer-komponenten från det gamla Context API och gör koden mer koncis och läsbar.
Typiska användningsscenarier för kontext inkluderar designteman (ljus/mörk), regionala inställningar och översättningar (i18n), användarautentisering, applikationsinställningar och alla andra globala data som behövs av många komponenter på olika nästlingsnivåer. React-teamet rekommenderar att använda kontext för data som är globala för komponenternas underträd, men inte för hela applikationen.
Enligt React Team — Context documentation (2025) är felaktig användning av kontext en av de främsta orsakerna till prestandaproblem i React-applikationer. Varje ändring av värdet i Providern orsakar omrendering av alla konsumenter, oavsett vilken del av data som ändrades. Optimering via useMemo och uppdelning av kontexter löser detta problem.
import { createContext, useContext } from 'react';
// Skapa kontext med standardvärde
const ThemeContext = createContext('ljust');
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={`btn-${theme}`}>Click</button>;
}
Kontextmekanismen i React implementeras genom mönstret Provider-Consumer. createContext returnerar ett objekt med två entiteter: Provider — komponenten som skickar värdet, och själva kontextobjektet som används i useContext. Providern monteras i komponentträdet och skickar värdet till alla underordnade element oavsett nästlingsdjup.
När React stöter på ett anrop till useContext, rör det sig uppåt genom fiber-trädet för att hitta den närmaste Providern för den kontexten. Om Providern hittas, returneras dess värde. Om Providern inte hittas, returneras standardvärdet som skickades till createContext. Denna sökning sker vid varje rendering, men tack vare memorering av fiber-noder är den mycket snabb och påverkar inte prestandan.
Enligt React — Context internals (2024) använder den interna implementeringen av useContext en länkad lista av hooks, liknande useState. Varje hook lagrar en referens till fiber-noden, vilket gör att React snabbt kan avgöra vilken Provider som motsvarar den kontexten. Om Providern uppdaterar värdet, markerar React alla fiber-noder som använder denna kontext för omrendering.
Provider-komponenter kan nästlas inuti varandra och skapa en hierarki av kontexter. Varje underordnad Provider åsidosätter förälderns värde för sitt underträd. Detta är användbart när en skärm behöver ett ljust tema och ett nästlat modalt fönster behöver ett mörkt tema. useContext returnerar alltid värdet från den närmaste Providern högre upp i trädet.
const UserContext = createContext(null);
const ThemeContext = createContext('ljust');
function App() {
return (
<UserContext.Provider value={{ name: 'Alice' }}>
<ThemeContext.Provider value='dark'>
<Profile />
</ThemeContext.Provider>
</UserContext.Provider>
);
}
Funktionen createContext(defaultValue) skapar ett kontextobjekt. Parametern defaultValue används när en komponent anropar useContext, men det inte finns någon motsvarande Provider högre upp i trädet. Utan defaultValue kommer useContext att returnera undefined, vilket kan leda till oväntade fel. Det rekommenderas att alltid skicka en meningsfull standardvärde eller null.
Att skapa en anpassad provider är ett vanligt mönster för inkapsling av kontextlogik. Inuti en sådan provider lagras tillståndet (via useState eller useReducer) och tillhandahålls via Providerns value-prop. Detta gör att implementeringsdetaljer kan döljas från konsumerande komponenter och kontexthanteringslogiken kan centraliseras på ett ställe.
// Anpassad provider med tillståndshantering
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>
);
}
I funktionella komponenter är useContext det enda sättet att få tillgång till kontext. Det ersätter Consumer-komponenten från det gamla Context API, som krävde render-prop-mönstret: <ThemeContext.Consumer>{value => ...}</ThemeContext.Consumer>. useContext gör koden mer linjär och läsbar, särskilt när man arbetar med flera kontexter i en komponent.
När du använder flera kontexter i en komponent, anropa bara useContext flera gånger för varje kontext. Varje anrop returnerar värdet från motsvarande Provider. Ordningen på anropen spelar ingen roll, eftersom varje kontext är en oberoende entitet. React optimerar flera anrop genom samma fiber-referenssystem.
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>
);
}
Valet mellan useContext och Redux beror på skalan och komplexiteten av tillståndshantering. useContext + useReducer är ett lättviktsalternativ till Redux för små och medelstora applikationer. Det kräver ingen installation av externt bibliotek, är lättare att lära sig och tillräckligt för de flesta uppgifter. Redux är motiverat när en strikt arkitektur med middleware, utvecklingsverktyg och oföränderliga uppdateringar behövs.
Den största fördelen med Redux framför useContext är optimering av omrenderingar. Som standard, när värdet i Providern ändras, renderas alla kontextkonsumenter om. Redux med useSelector och shallowEqual låter komponenter prenumerera endast på specifika delar av tillståndet, vilket avsevärt minskar antalet omrenderingar i stora applikationer. Kontext kan också optimeras genom att dela upp den i flera små kontexter.
| Kriterium | useContext | Redux |
|---|---|---|
| Komplexitet | Inga externa beroenden | Kräver konfiguration av store och middleware |
| Omrenderingar | Alla konsumenter vid varje ändring | Endast prenumeranter på en specifik slice |
| DevTools | React DevTools | Redux DevTools med time-travel |
| Middleware | Stöds inte | Redux Thunk, Saga, Observable |
| När välja | Medelstora appar, 3-5 kontexter | Stora appar med komplex affärslogik |
Enligt Redux maintainers — When to use Redux (2024) behöver 70% av React-applikationer inte Redux. Om du har färre än 50 komponenter och tillståndet inte har komplex logik med cachelagring, debounce och biverkningar — är useContext + useReducer mer än tillräckligt. Redux lägger till boilerplate och bör användas medvetet.
Det vanligaste misstaget är återskapande av value-objektet vid varje rendering av Providern. Om du skickar value={{ user, login }} till Providern, skapas ett nytt objekt vid varje rendering av Providern, vilket orsakar omrendering av alla konsumenter, även om data inte har ändrats. Lösningen — memorering av value via useMemo eller användning av separata kontexter för ofta och sällan ändrade data.
// ❌ Nytt objekt vid varje rendering — alla konsumenter renderas om
<AuthContext.Provider value={{ user, login }}>{children}</AuthContext.Provider>
// ✅ Memorerat värde — omrendering endast när användare eller login ändras
const authValue = useMemo(() => ({ user, login }), [user, login]);
<AuthContext.Provider value={authValue}>{children}</AuthContext.Provider>
För att lösa problemet med ”en stor kontext”, dela upp det globala tillståndet i logiska grupper: AuthContext, ThemeContext, I18nContext. Varje kontext ansvarar för sitt eget område och uppdateras oberoende. Detta är enklare än att försöka optimera en enda gigantisk kontext via useMemo och ger mer förutsägbart beteende för omrenderingar.
Vanliga frågor
Ja, om du skickar en mutatorfunktion i Providerns value. Det typiska mönstret är att lagra tillstånd i Providern och skicka både data och funktioner för att uppdatera dem via useContext. Underordnade komponenter anropar dessa funktioner och tillståndsändringen i Providern uppdaterar automatiskt alla konsumenter. Detta är en grundläggande ersättning för Redux i små applikationer.
För enkla scenarier är useContext snabbare på grund av avsaknaden av overhead från store och middleware. Men vid frekventa uppdateringar med många konsumenter vinner Redux, eftersom dess väljare (useSelector) prenumererar på specifika delar av tillståndet, medan useContext renderar om alla konsumenter vid varje ändring. För applikationer med hög uppdateringsfrekvens (animationer, realtid) bör valet vara Redux eller specialiserade bibliotek.
Nej. useContext, precis som alla hooks, kan bara anropas inuti en funktionell React-komponent eller en anpassad hook. Om du behöver kontextvärdet i en vanlig funktion (t.ex. i ett verktyg eller en tjänst), skicka det som en parameter från komponenten eller använd en separat modul med globalt tillstånd utanför React.
Typning av kontext i TypeScript — att ange typen i createContext: createContext<AuthContextType | null>(null). Detta garanterar att useContext(AuthContext) returnerar ett värde av rätt typ. Ett bekvämt mönster är att skapa en anpassad hook useAuth som anropar useContext, kontrollerar null och kastar ett lättförståeligt fel: „useAuth must be used within AuthProvider”.
Den vanligaste orsaken är att den konsumerande komponenten befinner sig utanför motsvarande Provider. Kontrollera att Providern omger hela underträdet där useContext används. Den andra orsaken är att Providern skickas till ett annat kontextobjekt: utvecklaren skapar kontexten genom anrop till createContext, men använder useContext med en annan instans av createContext.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också