Wat is Context API?
Context API is een manier om data te delen met meerdere componenten in je app, zonder dat je props door elk component moet doorgeven.
Simpel gezegd:
Context is zoals een doos waar je data in stopt. Elk component in je app kan dan uit die doos halen wat het nodig heeft, zonder dat je alles handmatig moet doorgeven.
Wat kun je delen met Context?
- Wie is er ingelogd? (gebruikersinfo)
- Dark mode of light mode? (theme)
- Welke taal gebruikt de app? (Nederlands/Engels)
- Winkelwagen items (e-commerce)
Het Probleem: Props Drilling
Stel je voor: je bouwt een webshop. Je hebt deze component structuur:
App
└── HomePage
└── ProductList
└── ProductCard // Hier wil je de username tonen!
Je wilt in ProductCard de username tonen (bijvoorbeeld: "Jan, voeg toe aan winkelwagen"). Zonder Context moet je de username als prop doorgeven door ELKE laag:
// App.jsx - Hier begint het
function App() {
const username = "Jan";
return <HomePage username={username} />;
}
// HomePage.jsx - Gebruikt username NIET, geeft alleen door
function HomePage({ username }) {
return (
<div>
<h1>Welkom op onze webshop</h1>
<ProductList username={username} />
</div>
);
}
// ProductList.jsx - Gebruikt username ook NIET, geeft alleen door
function ProductList({ username }) {
const products = ["Laptop", "Muis", "Toetsenbord"];
return (
<div>
{products.map(product => (
<ProductCard
key={product}
name={product}
username={username} // Moet het hier weer doorgeven
/>
))}
</div>
);
}
// ProductCard.jsx - EINDELIJK! Hier gebruiken we het pas
function ProductCard({ name, username }) {
return (
<div>
<h3>{name}</h3>
<p>Prijs: 99 euro</p>
<button>{username}, voeg toe aan winkelwagen</button>
</div>
);
}
Props Drilling = Vervelend!
Je moet username door HomePage en ProductList geven, terwijl die componenten het zelf niet eens gebruiken! Ze geven het alleen maar door naar de volgende laag.
Dit wordt al snel een probleem:
- Veel typen voor niks (3x username als prop doorgeven)
- Moeilijk te onderhouden (stel je voegt nog een laag toe tussen ProductList en ProductCard)
- Foutgevoelig (vergeet je 1 prop op 1 plek? Error!)
- HomePage en ProductList hoeven username niet te kennen, maar moeten het wel doorgeven
En nu komt het ergste: als je username ook in een Footer wilt tonen, moet je het OPNIEUW door alle componenten geven!
De Oplossing: Context API
Met Context API kun je data direct delen met elk component dat het nodig heeft!
Met Context:
ProductCard kan de username direct uit de Context halen. HomePage en ProductList hoeven NIETS te weten over username!
Hoe werkt het?
Context API bestaat uit 3 stappen:
- Maak een Context - de doos waar je data in stopt
- Geef de data - vul de doos met data via een Provider
- Gebruik de data - pak uit de doos wat je nodig hebt met useContext
Denk aan een schoolkluis:
Context = de kluis waar je je spullen in bewaart
Provider = de school die kluizen beschikbaar maakt
useContext = je sleutel om bij je kluis te komen
Iedereen met een sleutel kan bij hun eigen kluis, zonder dat anderen het hoeven door te geven!
Het verschil visualiseren
ZONDER Context (Props Drilling):
App (heeft username)
→ geef door →
HomePage (gebruikt het niet, geeft door)
→ geef door →
ProductList (gebruikt het niet, geeft door)
→ geef door →
ProductCard (gebruikt het eindelijk!)
MET Context:
App (zet username in Context)
HomePage (hoeft niets door te geven)
ProductList (hoeft niets door te geven)
ProductCard (haalt username direct uit Context)
Wanneer Gebruiken?
Gebruik Context wanneer:
- Data nodig is in VEEL verschillende componenten
- Je props door 3 of meer levels moet doorgeven
- Het gaat om globale dingen zoals: user info, theme, taal
- Je dezelfde data op meerdere plekken nodig hebt
Gebruik GEEN Context wanneer:
- Je props maar 1 of 2 levels door moet geven (dan is props prima)
- Het gaat om data die maar 1 component nodig heeft
- De data heel vaak verandert (kan traag worden)
Praktische voorbeelden
Goed voor Context:
- Ingelogde gebruiker (nodig op homepage, in navbar, in footer, in product cards)
- Dark/Light mode (hele app moet weten welke kleur te gebruiken)
- Winkelwagen (navbar toont aantal items, meerdere pagina's tonen winkelwagen)
Niet goed voor Context:
- Formulier data (blijft binnen 1 formulier component)
- Toggle state van 1 dropdown (alleen die dropdown gebruikt het)
- API data die alleen op 1 pagina wordt getoond
Simpel Voorbeeld: Username Delen
Laten we een heel simpel voorbeeld maken om te leren hoe Context werkt. We delen een username door de hele app.
Stap 1: Maak de Context
Maak een nieuw bestand: src/context/UserContext.jsx
import { createContext } from "react";
// Maak de Context (de doos)
const UserContext = createContext();
export default UserContext;
createContext() maakt een lege doos waar je straks data in stopt
Stap 2: Geef de Data met Provider
In je App.jsx, wikkel je hele app in de Provider en geef de data mee:
import UserContext from "./context/UserContext";
import HomePage from "./components/HomePage";
function App() {
const username = "Jan";
return (
// Wikkel je app in de Provider
<UserContext.Provider value={username}>
<HomePage />
</UserContext.Provider>
);
}
export default App;
Provider = maakt de data beschikbaar voor alle componenten binnen de tags
value = de data die je wilt delen (hier: username)
Stap 3: Gebruik de Data met useContext
Nu kun je in ELK component (hoe diep ook!) de username ophalen:
import { useContext } from "react";
import UserContext from "../context/UserContext";
function ProductCard({ name }) {
// Haal de username uit de Context
const username = useContext(UserContext);
return (
<div>
<h3>{name}</h3>
<button>{username}, voeg toe aan winkelwagen</button>
</div>
);
}
export default ProductCard;
useContext() haalt data uit de Context
Nu hoef je username NIET meer door HomePage en ProductList te geven!
Het Complete Voorbeeld
// src/context/UserContext.jsx
import { createContext } from "react";
const UserContext = createContext();
export default UserContext;
// src/App.jsx
import UserContext from "./context/UserContext";
import HomePage from "./components/HomePage";
function App() {
const username = "Jan";
return (
<UserContext.Provider value={username}>
<HomePage />
</UserContext.Provider>
);
}
// src/components/HomePage.jsx
import ProductList from "./ProductList";
function HomePage() {
// HomePage hoeft username NIET te kennen!
return (
<div>
<h1>Webshop</h1>
<ProductList />
</div>
);
}
// src/components/ProductList.jsx
import ProductCard from "./ProductCard";
function ProductList() {
// ProductList hoeft username ook NIET te kennen!
const products = ["Laptop", "Muis", "Toetsenbord"];
return (
<div>
{products.map(product => (
<ProductCard key={product} name={product} />
))}
</div>
);
}
// src/components/ProductCard.jsx
import { useContext } from "react";
import UserContext from "../context/UserContext";
function ProductCard({ name }) {
// ProductCard haalt username direct uit Context!
const username = useContext(UserContext);
return (
<div>
<h3>{name}</h3>
<button>{username}, voeg toe aan winkelwagen</button>
</div>
);
}
Zie je het verschil?
HomePage en ProductList hoeven NIETS met username te doen. ProductCard pakt het direct uit de Context. Veel cleaner en makkelijker!
Volgende Stap
Nu je begrijpt hoe Context werkt, kunnen we een echte AuthContext maken voor login/logout!
VolgendeAuthContext Setup
Maak een AuthContext voor login state met localStorage