useContext: essentie, toegangshook tot context en providers in React

Auteur: IT Sectr Gepubliceerd: 2026-07-04 Leestijd: 9 min

useContext — is een React hook die functionele componenten directe toegang geeft tot gegevens uit de context die via createContext is gemaakt. Context in React lost het probleem van props drilling op — het doorgeven van props via meerdere tussenliggende componenten die deze gegevens zelf niet gebruiken. Volgens React Documentation (2025), accepteert useContext het contextobject en retourneert de huidige waarde die is ingesteld door de dichtstbijzijnde Provider hoger in de componentenboom. Wanneer de waarde in de Provider verandert, worden alle componenten die useContext gebruiken automatisch opnieuw gerenderd.

Belangrijkste

  • useContext — hook voor het lezen van waarden uit React context zonder props drilling.
  • createContext — maakt een contextobject met een standaardwaarde en Provider-component.
  • Provider — een wrapper-component die de contextwaarde doorgeeft aan alle onderliggende elementen.
  • Herrenderen — verandering van waarde in de Provider veroorzaakt herrenderen van alle contextgebruikers.
  • Overslaan van tussenliggende componenten — useContext maakt gegevensoverdracht door meerdere niveaus van nesting mogelijk.

Wat is useContext in React

useContext — is een hook die in React 16.8 is toegevoegd samen met de andere hooks, waarmee je een waarde uit de React context kunt lezen. Context is een ingebouwd mechanisme in React, bedoeld voor het doorgeven van gegevens door de componentenboom zonder dat je handmatig props op elk niveau hoeft door te geven. useContext vervangt de Consumer-component uit de oude Context API en maakt de code beknopter en leesbaarder.

Typische gebruiksscenario’s voor context zijn ontwerpthema’s (licht/donker), regionale instellingen en vertalingen (i18n), gebruikersauthenticatie, applicatie-instellingen en andere globale gegevens die nodig zijn voor veel componenten op verschillende nestniveaus. Het React-team raadt aan om context te gebruiken voor gegevens die globaal zijn voor de subboom van componenten, maar niet voor de hele applicatie.

Volgens React Team — Context documentation (2025) is onjuist gebruik van context een van de belangrijkste oorzaken van prestatieproblemen in React-applicaties. Elke verandering van waarde in de Provider veroorzaakt herrenderen van alle gebruikers, ongeacht welk deel van de gegevens is veranderd. Optimalisatie via useMemo en het splitsen van contexten lost dit probleem op.

jsx
import { createContext, useContext } from 'react';

// Context aanmaken met standaardwaarde
const ThemeContext = createContext('licht');

function ThemedButton() {
    const theme = useContext(ThemeContext);
    return <button className={`btn-${theme}`}>Click</button>;
}

Hoe werkt context in React

Het contextmechanisme in React is geïmplementeerd via het Provider-Consumer-patroon. createContext retourneert een object met twee entiteiten: Provider — de component die de waarde doorgeeft, en het contextobject zelf dat in useContext wordt gebruikt. De Provider wordt in de componentenboom gemonteerd en geeft de waarde door aan alle onderliggende elementen, ongeacht de nestdiepte.

Wanneer React een useContext-aanroep tegenkomt, beweegt het omhoog door de fiberboom op zoek naar de dichtstbijzijnde Provider voor die context. Als de Provider wordt gevonden, wordt de waarde ervan geretourneerd. Als de Provider niet wordt gevonden, wordt de standaardwaarde geretourneerd die aan createContext is doorgegeven. Deze zoektocht vindt plaats bij elke render, maar dankzij memorisatie van fiber-knooppunten is deze zeer snel en beïnvloedt de prestaties niet.

Volgens React — Context internals (2024) gebruikt de interne implementatie van useContext een gelinkte lijst van hooks, vergelijkbaar met useState. Elke hook slaat een verwijzing op naar het fiber-knooppunt, waardoor React snel kan bepalen welke Provider bij die context hoort. Als de Provider de waarde bijwerkt, markeert React alle fiber-knooppunten die deze context gebruiken voor herrenderen.

Provider en geneste contexten

Provider-componenten kunnen in elkaar worden genest, waardoor een hiërarchie van contexten ontstaat. Elke onderliggende Provider overschrijft de waarde van de ouder voor zijn subboom. Dit is handig wanneer op het ene scherm een licht thema nodig is en in een genest modaal venster een donker thema. useContext retourneert altijd de waarde van de dichtstbijzijnde Provider hoger in de boom.

jsx
const UserContext = createContext(null);
const ThemeContext = createContext('licht');

function App() {
    return (
        <UserContext.Provider value={{ name: 'Alice' }}>
            <ThemeContext.Provider value='dark'>
                <Profile />
            </ThemeContext.Provider>
        </UserContext.Provider>
    );
}

Een provider maken met createContext

De functie createContext(defaultValue) maakt een contextobject. De parameter defaultValue wordt gebruikt wanneer een component useContext aanroept, maar er hoger in de boom geen corresponderende Provider is. Zonder defaultValue retourneert useContext undefined, wat kan leiden tot onverwachte fouten. Het wordt aanbevolen om altijd een zinvolle standaardwaarde of null door te geven.

Het maken van een aangepaste provider is een veelvoorkomend patroon voor het inkapselen van contextlogica. Binnen zo’n provider wordt de status opgeslagen (via useState of useReducer) en beschikbaar gesteld via de value-prop van de Provider. Dit verbergt implementatiedetails voor consumerende componenten en centraliseert de contextbeheerlogica op één plek.

jsx
// Aangepaste provider met statusbeheer
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>
    );
}

useContext gebruiken in onderliggende componenten

In functionele componenten is useContext de enige manier om toegang te krijgen tot context. Het vervangt de Consumer-component uit de oude Context API, die het render-prop-patroon vereiste: <ThemeContext.Consumer>{value => ...}</ThemeContext.Consumer>. useContext maakt de code linearer en leesbaarder, vooral bij het werken met meerdere contexten in één component.

Wanneer je meerdere contexten in één component gebruikt, roep je useContext gewoon meerdere keren aan voor elke context. Elke aanroep retourneert de waarde van de bijbehorende Provider. De volgorde van aanroepen doet er niet toe, omdat elke context een onafhankelijke entiteit is. React optimaliseert meerdere aanroepen via hetzelfde systeem van fiber-verwijzingen.

jsx
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>
    );
}

useContext vs Redux: wanneer wat kiezen

De keuze tussen useContext en Redux hangt af van de schaal en complexiteit van statusbeheer. useContext + useReducer is een lichte vervanging voor Redux voor kleine en middelgrote applicaties. Het vereist geen installatie van een externe bibliotheek, is gemakkelijker te leren en voldoende voor de meeste taken. Redux is gerechtvaardigd wanneer een strikte architectuur met middleware, ontwikkeltools en onveranderlijke updates nodig is.

Het belangrijkste voordeel van Redux boven useContext is optimalisatie van herrenderingen. Standaard, bij verandering van waarde in de Provider, worden alle contextgebruikers opnieuw gerenderd. Redux met useSelector en shallowEqual stelt componenten in staat om alleen op bepaalde delen van de status te abonneren, wat het aantal herrenderingen in grote applicaties aanzienlijk vermindert. Context kan ook worden geoptimaliseerd door splitsing in meerdere kleine contexten.

CriteriumuseContextRedux
ComplexiteitGeen externe afhankelijkhedenVereist configuratie van store en middleware
HerrenderingenAlle gebruikers bij elke veranderingAlleen geabonneerden op een specifieke slice
DevToolsReact DevToolsRedux DevTools met time-travel
MiddlewareNiet ondersteundRedux Thunk, Saga, Observable
Wanneer kiezenMiddelgrote apps, 3-5 contextenGrote apps met complexe bedrijfslogica

Volgens Redux maintainers — When to use Redux (2024) heeft 70% van de React-applicaties geen Redux nodig. Als je minder dan 50 componenten hebt en de status geen complexe logica heeft met caching, debounce en neveneffecten — is useContext + useReducer meer dan voldoende. Redux voegt boilerplate toe en moet bewust worden gebruikt.

Veelvoorkomende fouten met useContext

De meest voorkomende fout is het opnieuw aanmaken van het value-object bij elke render van de Provider. Als je value={{ user, login }} aan de Provider doorgeeft, wordt bij elke render van de Provider een nieuw object gemaakt, wat herrenderen van alle gebruikers veroorzaakt, zelfs als de gegevens niet zijn veranderd. De oplossing — memorisatie van value via useMemo of het gebruik van aparte contexten voor veel en weinig veranderende gegevens.

  • Overbodige herrenderingen — nieuw value-object bij elke Provider-render. Gebruik useMemo voor memorisatie van value.
  • Te grote context — één Provider met tientallen velden zorgt dat alle onderliggende componenten herrenderen bij verandering van elk veld. Verdeel in meerdere contexten op basis van betekenis.
  • Ontbreken van defaultValue — als de Provider niet wordt gevonden, retourneert useContext defaultValue, en als het undefined is — zal elke aanroep mislukken met een TypeError.
  • Geneste Providers van hetzelfde type — overschrijven van context op diepe niveaus kan verwarrend zijn en leiden tot onverwachte waarden.
jsx
// ❌ Nieuw object bij elke render — alle gebruikers herrenderen
<AuthContext.Provider value={{ user, login }}>{children}</AuthContext.Provider>

// ✅ Gememoriseerde waarde — herrenderen alleen wanneer gebruiker of login verandert
const authValue = useMemo(() => ({ user, login }), [user, login]);
<AuthContext.Provider value={authValue}>{children}</AuthContext.Provider>

Om het probleem van de „grote context” op te lossen, verdeel je de globale status in logische groepen: AuthContext, ThemeContext, I18nContext. Elke context is verantwoordelijk voor zijn eigen domein en werkt onafhankelijk bij. Dit is eenvoudiger dan proberen één gigantische context via useMemo te optimaliseren en geeft voorspelbaarder herrendergedrag.

Veelgestelde vragen

Kan ik de context wijzigen vanuit een onderliggende component?

Ja, als je een mutator-functie in de value van de Provider doorgeeft. Het typische patroon is het opslaan van status in de Provider en het doorgeven van zowel gegevens als functies voor het bijwerken ervan via useContext. Onderliggende componenten roepen deze functies aan en de statusverandering in de Provider werkt automatisch alle gebruikers bij. Dit is een basisvervanging voor Redux in kleine applicaties.

Wat is sneller — useContext of Redux?

Voor eenvoudige scenario’s is useContext sneller vanwege het ontbreken van overhead van store en middleware. Maar bij frequente updates met een groot aantal gebruikers wint Redux, omdat de selectors (useSelector) zich abonneren op specifieke delen van de status, terwijl useContext alle gebruikers herrendert bij elke verandering. Voor applicaties met een hoge updatefrequentie (animaties, real-time) moet de keuze vallen op Redux of gespecialiseerde bibliotheken.

Kan ik useContext buiten een React-component gebruiken?

Nee. useContext kan, net als alle hooks, alleen worden aangeroepen binnen een functionele React-component of een aangepaste hook. Als je de contextwaarde in een gewone functie nodig hebt (bijvoorbeeld in een utility of service), geef deze dan als parameter door vanuit de component of gebruik een aparte module met globale status buiten React.

Hoe werkt useContext met TypeScript?

Het typeren van context in TypeScript — het specificeren van het type in createContext: createContext<AuthContextType | null>(null). Dit garandeert dat useContext(AuthContext) een waarde van het juiste type retourneert. Een handig patroon is het maken van een aangepaste hook useAuth die useContext aanroept, controleert op null en een begrijpelijke fout geeft: „useAuth must be used within AuthProvider”.

Waarom retourneert useContext undefined terwijl de Provider bestaat?

De meest voorkomende oorzaak is dat de consumerende component zich buiten de corresponderende Provider bevindt. Controleer of de Provider de hele subboom omvat waarin useContext wordt gebruikt. De tweede oorzaak is dat de Provider aan een ander contextobject wordt doorgegeven: de ontwikkelaar maakt context aan via createContext, maar gebruikt useContext met een andere instantie van createContext.

Samenvatting

  • useContext — hook voor het lezen van waarden uit React context, waardoor props drilling overbodig wordt.
  • createContext — maakt een contextobject met Provider voor gegevensoverdracht en defaultValue voor het geval zonder Provider.
  • Memorisatie van value — gebruik useMemo voor value in de Provider om onnodig herrenderen van gebruikers te voorkomen.
  • Splitsen van contexten — verdeel de globale status in meerdere kleine contexten op basis van logische groepen.
  • Provider-hiërarchie — Providers van hetzelfde type kunnen worden genest om de waarde in een deel van de boom te overschrijven.
  • useContext + useReducer — lichte vervanging voor Redux voor middelgrote applicaties zonder externe afhankelijkheden.
  • Vervangt Redux niet — kies voor complexe logica met middleware en frequente updates Redux met selectors.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook