# Top 30 React Interview Fragen
> Vollständiger Leitfaden zu den 30 häufigsten Fragen in technischen React-Interviews mit ausführlichen Antworten und Codebeispielen.
- Published: 2026-01-31
- Updated: 2026-04-21
- Author: SharpSkill
- Tags: react interview, frontend interview, react questions, javascript, technical interview
- Reading time: 18 min
---
Technische React-Interviews prüfen das Verständnis grundlegender Konzepte, fortgeschrittener Patterns und Best Practices. Dieser Leitfaden fasst die 30 am häufigsten gestellten Fragen zusammen, mit ausführlichen Antworten und Codebeispielen zur effektiven Vorbereitung.
> **Tipp zur Vorbereitung**
>
> Diese Fragen sind nach Schwierigkeitsgrad sortiert. Die Grundlagen zu beherrschen, bevor fortgeschrittene Konzepte angegangen werden, ermöglicht eine strukturiertere Vorbereitung.
## React-Grundlagen
### 1. Was ist das Virtual DOM und warum nutzt React es?
Das Virtual DOM ist eine leichtgewichtige JavaScript-Repräsentation des echten DOM. React nutzt diese Abstraktion, um Interface-Aktualisierungen zu optimieren.
Der Prozess läuft in drei Schritten ab: React erzeugt zunächst eine virtuelle Kopie des DOM, vergleicht diese Kopie bei Änderungen mit der vorherigen Version (Diffing-Algorithmus) und wendet schließlich nur die notwendigen Änderungen auf das echte DOM an (Reconciliation).
```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}
)
}
```
Dieser Ansatz vermeidet kostspielige DOM-Operationen und ermöglicht performante Aktualisierungen auch bei komplexen Oberflächen.
### 2. Was ist der Unterschied zwischen Function- und Class-Components?
Function-Components sind JavaScript-Funktionen, die Props erhalten und JSX zurückgeben. Seit React 16.8 erlauben Hooks die Nutzung von State und Lifecycle innerhalb von Function-Components.
```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
}
}
```
Function-Components sind heute der Standard. Class-Components werden weiterhin unterstützt, für neue Projekte aber nicht mehr empfohlen.
### 3. Wie funktioniert JSX?
JSX ist eine Syntaxerweiterung für JavaScript, die es erlaubt, Markup im Code zu schreiben. Es handelt sich nicht um HTML, sondern um JavaScript in anderer Form.
```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')
)
```
Zu den Unterschieden zu HTML gehören: `className` statt `class`, `htmlFor` statt `for`, camelCase für Attribute (`onClick`, `tabIndex`) und das verpflichtende Schließen selbstschließender Tags.
### 4. Was ist der Unterschied zwischen State und Props?
Props sind Daten, die von einer Parent-Komponente an eine Child-Komponente übergeben werden. Sie sind schreibgeschützt. State ist der interne Zustand einer Komponente und kann über Setter verändert werden.
```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
```
Die Grundregel lautet: Props fließen nach unten (Parent → Child), State ist lokal zu jeder Komponente.
### 5. Warum sind Keys in Listen wichtig?
Keys helfen React dabei, zu erkennen, welche Elemente in einer Liste verändert, hinzugefügt oder entfernt wurden. Ohne eindeutige und stabile Keys kann React unerwartetes Verhalten zeigen.
```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. useState erklären und häufige Stolperfallen
`useState` verwaltet lokalen State in einer Function-Component. Der Setter akzeptiert entweder einen Wert oder eine Update-Funktion.
```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. Wie funktioniert useEffect mit seinem Dependency-Array?
`useEffect` führt Seiteneffekte nach dem Rendern aus. Das Dependency-Array steuert, wann der Effekt ausgeführt wird.
```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**
>
> Das Plugin `eslint-plugin-react-hooks` sollte immer aktiviert sein, um fehlende Dependencies zu erkennen. Diese Regel verhindert viele schwer zu diagnostizierende Bugs.
### 8. Wann sollten useMemo und useCallback verwendet werden?
Diese Hooks ermöglichen Memoization, um unnötige Neuberechnungen oder Neuerzeugungen zu vermeiden. Ein übermäßiger Einsatz sollte jedoch vermieden werden.
```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}
}
```
Diese Hooks sollten nur eingesetzt werden, wenn ein konkretes Performance-Problem besteht oder um Referenzen für memoisierte Komponenten stabil zu halten.
### 9. Wie funktioniert useRef und welche Anwendungsfälle gibt es?
`useRef` erstellt eine veränderbare Referenz, die zwischen Renders persistiert, ohne beim Verändern einen Re-Render auszulösen.
```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. useContext erklären und wann einzusetzen
`useContext` greift auf einen React-Context zu, ohne Prop Drilling betreiben zu müssen. Ideal für globale Daten wie Theme oder eingeloggten Nutzer.
```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 (
)
}
```
## Fortgeschrittene Patterns
### 11. Was ist eine Higher-Order Component (HOC)?
Eine HOC ist eine Funktion, die eine Komponente entgegennimmt und eine neue, erweiterte Komponente zurückgibt. Seit der Einführung von Hooks seltener im Einsatz, aber in einigen Bibliotheken weiterhin präsent.
```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. Das Render-Props-Pattern erklären
Das Render-Props-Pattern teilt Logik zwischen Komponenten über eine Prop, die eine Funktion ist.
```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. Wie erstellt man einen Custom Hook?
Custom Hooks extrahieren zustandsbehaftete Logik und ermöglichen deren Wiederverwendung zwischen Komponenten.
```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. Was ist das Compound-Components-Pattern?
Dieses Pattern erzeugt Komponenten, die implizit zusammenarbeiten, vergleichbar mit den Tags `