# Top 30 React-sollicitatievragen (2026)
> De 30 belangrijkste React-sollicitatievragen met gedetailleerde antwoorden, codevoorbeelden en moderne patronen voor een effectieve voorbereiding.
- Published: 2026-01-31
- Updated: 2026-04-21
- Author: SharpSkill
- Tags: react interview, frontend interview, react questions, javascript, technical interview
- Reading time: 18 min
---
Bij technische sollicitatiegesprekken over React wordt het begrip van de fundamentele concepten, de geavanceerde patronen en de beste praktijken getoetst. Deze gids bundelt de 30 vragen die het vaakst voorbijkomen, met uitgewerkte antwoorden en codevoorbeelden voor een doelgerichte voorbereiding.
> **Voorbereidingsadvies**
>
> Deze vragen zijn geordend op moeilijkheidsgraad. Het beheersen van de basis voordat de geavanceerde onderwerpen aan bod komen, zorgt voor een gestructureerdere voorbereiding.
## Fundamenten van React
### 1. Wat is de Virtual DOM en waarom gebruikt React deze?
De Virtual DOM is een lichte JavaScript-representatie van de echte DOM. React gebruikt deze abstractie om updates van de interface te optimaliseren.
Het proces verloopt in drie stappen: React maakt eerst een virtuele kopie van de DOM, vergelijkt die kopie vervolgens met de vorige versie zodra er wijzigingen optreden (diffing-algoritme) en past ten slotte alleen de noodzakelijke aanpassingen toe op de echte DOM (reconciliatie).
```jsx
// Simplified example of the concept
// When state changes, React doesn't recreate the entire DOM
function Counter() {
const [count, setCount] = useState(0)
// Only the span containing count will be updated in the real DOM
// The rest of the component is untouched
return (
Counter
{count}
)
}
```
Deze aanpak vermijdt dure DOM-operaties en maakt performante updates mogelijk, zelfs bij complexe interfaces.
### 2. Wat is het verschil tussen functionele en class-componenten?
Functionele componenten zijn JavaScript-functies die props ontvangen en JSX retourneren. Sinds React 16.8 maken hooks het mogelijk om state en lifecycle te gebruiken binnen functionele componenten.
```jsx
// Functional component (recommended)
// More concise, easier to test, supports hooks
function Welcome({ name }) {
const [visits, setVisits] = useState(0)
useEffect(() => {
setVisits(v => v + 1)
}, [])
return
Hello {name}, visit #{visits}
}
// Class component (legacy)
// More verbose, requires this binding
class WelcomeClass extends React.Component {
state = { visits: 0 }
componentDidMount() {
this.setState(prev => ({ visits: prev.visits + 1 }))
}
render() {
return
}
}
```
Functionele componenten vormen vandaag de standaard. Class-componenten worden nog ondersteund, maar worden niet meer aanbevolen voor nieuwe projecten.
### 3. Hoe werkt JSX?
JSX is een syntaxuitbreiding van JavaScript die toelaat om markup in de code te schrijven. Het is geen HTML, maar vermomde JavaScript.
```jsx
// What we write (JSX)
const element = (
Title
Paragraph
)
// What Babel compiles (pure JavaScript)
const element = React.createElement(
'div',
{ className: 'container' },
React.createElement('h1', null, 'Title'),
React.createElement('p', null, 'Paragraph')
)
```
Enkele verschillen met HTML: `className` in plaats van `class`, `htmlFor` in plaats van `for`, camelCase voor attributen (`onClick`, `tabIndex`) en verplichte sluiting van zelfsluitende tags.
### 4. Wat is state versus props?
Props zijn gegevens die een oudercomponent doorgeeft aan een kind. Ze zijn alleen-lezen. State is de interne toestand van een component, aanpasbaar via setters.
```jsx
// UserCard.jsx
// name and role are props (immutable)
function UserCard({ name, role }) {
// isExpanded is state (mutable)
const [isExpanded, setIsExpanded] = useState(false)
return (
{name}
{role}
{/* Modifying state triggers a re-render */}
{isExpanded && }
)
}
// Usage
```
De fundamentele regel: props stromen naar beneden (ouder → kind), state blijft lokaal in elk component.
### 5. Waarom zijn keys belangrijk in lijsten?
Keys helpen React om te bepalen welke elementen in een lijst zijn gewijzigd, toegevoegd of verwijderd. Zonder unieke en stabiele keys kan React zich onverwacht gedragen.
```jsx
// ❌ Bad practice: index as key
// Problem: if order changes, React loses tracking
{items.map((item, index) => (
))}
// ✅ Good practice: unique and stable identifier
{items.map(item => (
))}
// Concrete example of the problem with indices
function TodoList() {
const [todos, setTodos] = useState([
{ id: 1, text: 'Learn React' },
{ id: 2, text: 'Create a project' }
])
// When deleting the first element with key={index}
// React will think element 0's content changed
// instead of understanding an element was removed
return (
{todos.map(todo => (
{todo.text}
))}
)
}
```
## React Hooks
### 6. Leg useState uit en de veelvoorkomende valkuilen
`useState` beheert de lokale state in een functioneel component. De setter accepteert een waarde of een updatefunctie.
```jsx
// Declaration with initial value
const [count, setCount] = useState(0)
// ❌ Pitfall: multiple updates in the same cycle
function increment() {
setCount(count + 1) // count = 0, sets 1
setCount(count + 1) // count = 0 still, sets 1
setCount(count + 1) // count = 0 still, sets 1
// Final result: 1 (not 3)
}
// ✅ Solution: use the update function
function incrementCorrect() {
setCount(prev => prev + 1) // 0 → 1
setCount(prev => prev + 1) // 1 → 2
setCount(prev => prev + 1) // 2 → 3
// Final result: 3
}
// ❌ Pitfall: object mutation
const [user, setUser] = useState({ name: 'Alice', age: 25 })
user.age = 26 // Direct mutation, no re-render
// ✅ Solution: create a new object
setUser({ ...user, age: 26 })
// or
setUser(prev => ({ ...prev, age: 26 }))
```
### 7. Hoe werkt useEffect met zijn dependency array?
`useEffect` voert side effects uit na het renderen. De dependency array bepaalt wanneer het effect draait.
```jsx
// Executed on every render (rare, usually avoid)
useEffect(() => {
console.log('Render completed')
})
// Executed only on mount (equivalent to componentDidMount)
useEffect(() => {
console.log('Component mounted')
// Cleanup on unmount (equivalent to componentWillUnmount)
return () => {
console.log('Component unmounted')
}
}, [])
// Executed when userId changes
useEffect(() => {
async function fetchUser() {
const response = await fetch(`/api/users/${userId}`)
const data = await response.json()
setUser(data)
}
fetchUser()
}, [userId])
// ❌ Missing dependency - subtle bug
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1) // count is "captured" at its initial value
}, 1000)
return () => clearInterval(timer)
}, []) // count is missing from dependencies
// ✅ Fix with update function
useEffect(() => {
const timer = setInterval(() => {
setCount(prev => prev + 1) // No need for count in deps
}, 1000)
return () => clearInterval(timer)
}, [])
```
> **ESLint-regel**
>
> Schakel altijd `eslint-plugin-react-hooks` in om ontbrekende dependencies op te sporen. Deze regel voorkomt talrijke bugs die anders moeilijk te diagnosticeren zijn.
### 8. Wanneer moeten useMemo en useCallback worden gebruikt?
Deze hooks maken memoïsatie mogelijk om overbodige herberekeningen of herdefinities te vermijden. Overmatig gebruik moet vermeden worden.
```jsx
// useMemo: memoizes a computed value
function ProductList({ products, filter }) {
// Recalculated only if products or filter change
const filteredProducts = useMemo(() => {
console.log('Filtering...')
return products.filter(p => p.category === filter)
}, [products, filter])
return
{filteredProducts.map(p =>
{p.name}
)}
}
// useCallback: memoizes a function
function ParentComponent() {
const [count, setCount] = useState(0)
// Without useCallback, handleClick is recreated on every render
// Causing unnecessary re-renders of ExpensiveChild
const handleClick = useCallback((id) => {
console.log('Clicked:', id)
}, []) // Empty deps = stable function
return (
<>
{count}
{/* React.memo on ExpensiveChild for this to be effective */}
>
)
}
// ❌ Over-optimization: not needed here
const SimpleComponent = () => {
// This calculation is trivial, useMemo adds overhead
const doubled = useMemo(() => 2 * 2, [])
return {doubled}
}
```
Deze hooks horen alleen ingezet te worden wanneer er een daadwerkelijk performantieprobleem is vastgesteld of om stabiele referenties door te geven aan gememoïseerde componenten.
### 9. Hoe werkt useRef en wat zijn de toepassingen?
`useRef` creëert een muteerbare referentie die tussen renders blijft bestaan zonder een nieuwe render te triggeren bij wijziging.
```jsx
// Case 1: Access a DOM element
function TextInput() {
const inputRef = useRef(null)
const focusInput = () => {
inputRef.current.focus()
}
return (
<>
>
)
}
// Case 2: Store a mutable value without re-render
function Timer() {
const [seconds, setSeconds] = useState(0)
const intervalRef = useRef(null)
const start = () => {
// Store the interval ID to be able to stop it
intervalRef.current = setInterval(() => {
setSeconds(s => s + 1)
}, 1000)
}
const stop = () => {
clearInterval(intervalRef.current)
}
return (
{seconds}s
)
}
// Case 3: Keep the previous value
function usePrevious(value) {
const ref = useRef()
useEffect(() => {
ref.current = value
}, [value])
return ref.current
}
```
### 10. Leg useContext uit en wanneer het te gebruiken
`useContext` geeft toegang tot een React-context zonder prop drilling. Ideaal voor globale gegevens zoals een thema of de ingelogde gebruiker.
```jsx
// 1. Create the context
const ThemeContext = createContext({
theme: 'light',
toggleTheme: () => {}
})
// 2. Create the provider
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light')
const toggleTheme = useCallback(() => {
setTheme(prev => prev === 'light' ? 'dark' : 'light')
}, [])
// Memoize the value to avoid unnecessary re-renders
const value = useMemo(() => ({ theme, toggleTheme }), [theme, toggleTheme])
return (
{children}
)
}
// 3. Use the context
function ThemedButton() {
const { theme, toggleTheme } = useContext(ThemeContext)
return (
)
}
// 4. Wrap the application
function App() {
return (
)
}
```
## Geavanceerde patronen
### 11. Wat is een Higher-Order Component (HOC)?
Een HOC is een functie die een component aanneemt en een nieuw, verrijkt component retourneert. Minder gebruikt sinds de komst van hooks, maar nog steeds aanwezig in sommige bibliotheken.
```jsx
// HOC that adds logging
function withLogging(WrappedComponent) {
return function WithLogging(props) {
useEffect(() => {
console.log(`${WrappedComponent.name} mounted with props:`, props)
return () => {
console.log(`${WrappedComponent.name} unmounted`)
}
}, [])
return
}
}
// HOC that handles authentication
function withAuth(WrappedComponent) {
return function WithAuth(props) {
const { user, isLoading } = useAuth()
if (isLoading) return
if (!user) return
return
}
}
// Usage
const ProtectedDashboard = withAuth(Dashboard)
const LoggedButton = withLogging(Button)
```
### 12. Leg het Render Props-patroon uit
Het Render Props-patroon deelt logica tussen componenten via een prop die een functie is.
```jsx
// Component with render prop
function MouseTracker({ render }) {
const [position, setPosition] = useState({ x: 0, y: 0 })
useEffect(() => {
const handleMove = (e) => {
setPosition({ x: e.clientX, y: e.clientY })
}
window.addEventListener('mousemove', handleMove)
return () => window.removeEventListener('mousemove', handleMove)
}, [])
// Call the render function with data
return render(position)
}
// Usage
function App() {
return (
(
Position: {x}, {y}
)}
/>
)
}
// Modern version with custom hook (preferred)
function useMousePosition() {
const [position, setPosition] = useState({ x: 0, y: 0 })
useEffect(() => {
const handleMove = (e) => {
setPosition({ x: e.clientX, y: e.clientY })
}
window.addEventListener('mousemove', handleMove)
return () => window.removeEventListener('mousemove', handleMove)
}, [])
return position
}
function App() {
const { x, y } = useMousePosition()
return
Position: {x}, {y}
}
```
### 13. Hoe maak je een custom hook?
Custom hooks halen stateful logica eruit en maken ze herbruikbaar tussen componenten.
```jsx
// useLocalStorage.js
function useLocalStorage(key, initialValue) {
// Initialize with localStorage value or default
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key)
return item ? JSON.parse(item) : initialValue
} catch (error) {
console.error(error)
return initialValue
}
})
// Setter wrapper that syncs with localStorage
const setValue = useCallback((value) => {
try {
// Support update functions
const valueToStore = value instanceof Function ? value(storedValue) : value
setStoredValue(valueToStore)
window.localStorage.setItem(key, JSON.stringify(valueToStore))
} catch (error) {
console.error(error)
}
}, [key, storedValue])
return [storedValue, setValue]
}
// Usage
function Settings() {
const [theme, setTheme] = useLocalStorage('theme', 'light')
const [fontSize, setFontSize] = useLocalStorage('fontSize', 16)
return (
setFontSize(Number(e.target.value))}
/>
)
}
```
### 14. Wat is het Compound Components-patroon?
Dit patroon creëert componenten die impliciet samenwerken, zoals de tags `