Menu

React Interviewfragen und Antworten (React 19)

Rund 30 React-Interviewfragen vom Einstieg bis zum Profi, jede mit einer kurzen Antwort, die ein Interviewer akzeptieren würde, und mit Live-Code für die Fragen, die man besser sieht als liest.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Das sind die React-Interviewfragen, die am häufigsten vorkommen, nach Niveau gruppiert und so beantwortet, wie ein Interviewer es erwartet: kurz, korrekt für React 19 und mit dem Grund hinter der Regel. Wo das Verhalten zu sehen mehr bringt als darüber zu lesen, hat die Antwort einen Live-Editor, und bei einigen Fragen sollst du die Ausgabe der Konsole vorhersagen, bevor du den Code ausführst.

Bevor du klickst: Was gibt die Konsole unter der Vorschau aus, und was zeigt der Button? Die Antwort steht unten im Abschnitt für Einsteiger.

Fragen für Einsteiger

Was ist React?

React ist eine JavaScript-Bibliothek, mit der du Benutzeroberflächen aus Komponenten baust. Du schreibst Funktionen, die eine Beschreibung der UI für die aktuellen Daten zurückgeben, und wenn sich diese Daten ändern, findet React heraus, was sich geändert hat, und aktualisiert das DOM für dich. Es kümmert sich nur um die View-Schicht: Routing, Datenladen und Formulare kommen aus anderen Bibliotheken oder aus einem Framework wie Next.js.

Was ist JSX?

JSX ist eine Syntaxerweiterung, mit der du Markup in JavaScript schreibst. Ein Compiler (Babel, esbuild, SWC) macht aus jedem Tag einen Aufruf, der ein React-Element erzeugt, also wird <p className="note">{text}</p> zu einem Objekt mit type: 'p' und den Props. Weil es JavaScript ist, nutzt du className statt class, setzt Ausdrücke in {}, und jedes Tag muss geschlossen werden. Die Seite zu JSX behandelt die Regeln im Detail.

Was ist der Unterschied zwischen einer Komponente und einem Element?

Eine Komponente ist eine Funktion (oder Klasse), die Props annimmt und UI zurückgibt. Ein Element ist das einfache Objekt, das JSX erzeugt und das beschreibt, was gerendert werden soll: <Avatar size={40} /> ist ein Element, dessen type die Funktion Avatar ist. React ruft deine Komponente auf, um aus Elementen weitere Elemente zu machen, bis hinunter zu DOM-Tags. Elemente sind billig und unveränderlich; eine Komponente rufst du nie selbst auf.

Was ist der Unterschied zwischen Props und State?

Props werden vom Elternteil hineingegeben und sind in der Komponente schreibgeschützt. State gehört der Komponente, ändert sich im Lauf der Zeit über einen Setter, und jede Änderung plant einen neuen Render ein. Eine gängige Formulierung: Props konfigurieren eine Komponente, State ist ihr Gedächtnis. Derselbe Wert kann im Elternteil State und im Kind eine Prop sein.

Was loggt das erste Beispiel auf dieser Seite?

Es loggt logged: 0, und der Button zeigt Count: 1, nicht 2. State ist eine Momentaufnahme: count ist für den ganzen Render eine Konstante, also rechnen beide Aufrufe setCount(count + 1) mit 0 + 1, und das Log liest den alten Wert, weil der neue erst im nächsten Render existiert. Um zwei zu addieren, nutze zweimal die Updater-Form: setCount((c) => c + 1).

Warum brauchen Listen Keys, und warum ist der Index ein schlechter Key?

React nutzt den key, um jeden Listeneintrag dem aus dem vorherigen Render zuzuordnen. Wenn du den Array-Index nutzt und oben einen Eintrag einfügst, verschiebt sich jeder Index, also behält React den State jeder Zeile an ihrer alten Position und hängt ihn an die falschen Daten.

Hake Ada an und klicke dann auf „Add to top“: Das Häkchen springt in die neue erste Zeile. Ändere key={index} zu key={person.id} und versuche es erneut, dann bleibt das Häkchen bei Ada. In der Entwicklung warnt React außerdem, wenn Keys fehlen; die Vorschau läuft wie ein Produktions-Build, also siehst du diese Warnung hier nicht.

Was ist ein kontrolliertes Input?

Ein Input, dessen Wert aus dem React-State kommt: Du übergibst value und aktualisierst den State in onChange, also ist React die einzige Quelle der Wahrheit, und du kannst jeden Tastendruck validieren oder umformen. Ein unkontrolliertes Input hält seinen Wert selbst im DOM, und du liest ihn bei Bedarf über eine Ref oder die FormData des Formulars. Kontrollierte Inputs sind die Standardwahl, wenn die UI auf das reagiert, was getippt wird.

Was bedeutet Lifting State Up?

Wenn zwei Komponenten dieselben Daten brauchen, verschiebst du den State in ihr nächstes gemeinsames Elternteil und reichst ihn als Props nach unten, zusammen mit einer Funktion zum Ändern. Die Kinder besitzen keine eigenen Kopien mehr, also können sie sich nie widersprechen. Das ist die Standardantwort auf „wie teilen sich Geschwisterkomponenten State“, bevor man zu Context oder einem Store greift.

Was sind die Regeln der Hooks?

Ruf Hooks nur auf der obersten Ebene einer Komponente oder eines Custom Hooks auf, nie in Bedingungen, Schleifen oder verschachtelten Funktionen, und nur aus React-Funktionen, nicht aus einfachen JavaScript-Funktionen. React erkennt jeden Hook an der Reihenfolge der Aufrufe, also muss diese Reihenfolge bei jedem Render identisch sein. Das Paket eslint-plugin-react-hooks setzt beide Regeln durch.

Was ist ein Fragment?

Ein Fragment gruppiert mehrere Elemente, ohne einen DOM-Knoten hinzuzufügen: <>...</> oder <Fragment key={id}>, wenn du in einer Liste einen Key brauchst. Eine Komponente muss einen Root zurückgeben, und mit Fragments kann dieser Root aus mehreren Geschwistern bestehen, was in Tabellen und Flex-Layouts wichtig ist, wo ein zusätzliches div das Markup kaputt machen würde.

Fragen für Fortgeschrittene

Wie funktioniert das Abhängigkeitsarray von useEffect?

React führt den Effekt aus, nachdem der Render committet ist (meist nachdem der Browser gezeichnet hat), und dann erneut nach jedem späteren Render, in dem sich ein Wert im Array geändert hat (verglichen mit Object.is). Ohne Array läuft er nach jedem Render; mit [] einmal nach dem ersten Render. Jeder Wert aus der Komponente, den der Effekt liest, gehört ins Array, und der Linter sagt dir, wenn einer fehlt.

Wann läuft das Cleanup eines Effekts?

Die Funktion, die du aus einem Effekt zurückgibst, läuft, bevor der Effekt mit neuen Abhängigkeiten erneut läuft, und einmal, wenn die Komponente unmountet wird. Dort machst du rückgängig, was der Effekt eingerichtet hat: einen Timer löschen, einen Listener entfernen, eine Verbindung schließen.

Klicke auf „Switch room“ und beobachte die Konsole: Zuerst läuft das Cleanup für den alten Raum, dann verbindet sich der Effekt mit dem neuen. „Hide chat“ führt nur das Cleanup aus. In der Entwicklung fügt StrictMode beim Mounten ein zusätzliches Verbinden, Trennen, Verbinden hinzu, um zu prüfen, ob dein Cleanup funktioniert; die Vorschau läuft wie ein Produktions-Build, also siehst du nur die echte Abfolge.

Warum wirkt mein State in setInterval veraltet?

Der Interval-Callback ist eine Closure über das count aus dem Render, der ihn erzeugt hat. Mit leerem Abhängigkeitsarray läuft der Effekt nie erneut, also liest der Callback für immer dieses erste count.

broken erreicht 1 und bleibt stehen, weil jeder Tick 0 + 1 rechnet. fixed zählt weiter, weil die Updater-Funktion den neuesten Wert erhält. broken ins Abhängigkeitsarray aufzunehmen funktioniert auch, kostet aber, dass das Intervall jede Sekunde gelöscht und neu erzeugt wird.

Was ist Batching?

React fasst mehrere State-Updates zu einem einzigen Render zusammen. Seit React 18 gilt das überall: in Event-Handlern, Timeouts, Promises und nativen Event-Listenern. Wenn das DOM direkt nach einem Update aktualisiert sein muss, steigst du mit flushSync aus react-dom aus, aber das brauchst du selten.

Der Klick loggt ein einziges render 1 1 1, nicht drei Renders. Drei State-Updates in einem Timeout bedeuteten vor React 18 drei Renders.

Was loggt das? (Reihenfolge der Effekte)

Lies den Code und schreib die vier Zeilen auf, die die Konsole ausgeben wird, in der richtigen Reihenfolge, bevor du nachschaust.

Das Rendern läuft von oben nach unten: render App, dann render Child. Effekte laufen von unten nach oben, nachdem der ganze Baum committet ist: effect Child, dann effect App. Der Effekt eines Elternteils kann sich darauf verlassen, dass die Effekte seiner Kinder schon gelaufen sind.

Was ist der Unterschied zwischen useMemo und useCallback?

useMemo(() => compute(a, b), [a, b]) cacht das Ergebnis einer Berechnung. useCallback(fn, [deps]) cacht die Funktion selbst, ist also dasselbe wie useMemo(() => fn, [deps]). Beide helfen nur, wenn etwas weiter unten per Referenz vergleicht: ein Kind mit memo oder das Abhängigkeitsarray eines anderen Hooks. Seit React Compiler 1.0 (Oktober 2025) kann ein Build-Schritt diese Memoisierung automatisch hinzufügen, aber manuelle Memoisierung funktioniert weiterhin, und du siehst sie in den meisten Codebasen.

Was macht React.memo, und warum braucht es oft useCallback?

memo(Component) überspringt das erneute Rendern der Komponente, wenn ihre Props dieselben wie beim letzten Mal sind, einzeln mit Object.is verglichen. Eine inline im Elternteil geschriebene Funktion ist bei jedem Render eine neue Funktion, zählt also als geänderte Prop und hebelt memo aus. useCallback behält dieselbe Funktion zwischen Renders.

Leere die Konsole und klicke auf „Re-render parent“: Nur render inline handler erscheint. Das andere Kind hat dieselbe Funktion bekommen und wurde übersprungen. Entferne memo(...) um Button, und beide loggen bei jedem Klick, was zeigt, dass useCallback allein nichts bewirkt.

Was ist Context, und was kostet er?

Context reicht einen Wert an jede Komponente unter einem Provider, ohne ihn durch Props zu fädeln: createContext, dann in React 19 <ThemeContext value={theme}> (oder <ThemeContext.Provider>), und useContext(ThemeContext) zum Lesen. Der Preis: Jede Komponente, die den Context liest, rendert erneut, wenn sich der Wert ändert, und memo hält das nicht auf. Halte es günstig, indem du unabhängige Werte auf getrennte Contexts aufteilst, einen Objektwert in useMemo packst und schnell wechselnden State aus App-weitem Context heraushältst. Siehe useContext.

Was sind Refs, und wann nimmst du eine statt State?

useRef(initial) gibt ein Objekt zurück, dessen Eigenschaft current über Renders hinweg bestehen bleibt, und ihre Änderung löst keinen Render aus. Nutze eine Ref für Werte, von denen der Bildschirm nicht abhängt (eine Timer-ID, der vorherige Wert, ein Flag), und für DOM-Zugriff (<input ref={inputRef}>, dann inputRef.current.focus()). Wenn der Wert auf dem Bildschirm erscheint, gehört er in den State.

Was ist das virtuelle DOM, und was ist Reconciliation?

Bei jedem Render baut React einen neuen Baum aus Elementen und vergleicht ihn mit dem vorherigen; dieser Vergleich ist die Reconciliation. Wenn sich der Typ eines Elements geändert hat (ein div wurde zu einer section oder ProfileA zu ProfileB), zerstört React diesen Teilbaum samt State und baut einen neuen. Ist der Typ gleich, behält es den DOM-Knoten und aktualisiert die geänderten Props, und in Listen nutzt es Keys, um Kinder zuzuordnen. „Virtuelles DOM“ ist der populäre Name für diesen Baum im Speicher; die Geschwindigkeit kommt daher, nur das Geänderte anzufassen, nicht daher, dass der Baum selbst schnell wäre.

Was ist ein Custom Hook?

Eine Funktion, deren Name mit use beginnt und die andere Hooks aufruft, damit du zustandsbehaftete Logik zwischen Komponenten wiederverwenden kannst: useOnlineStatus, useLocalStorage, useDebouncedValue. Jede Komponente, die ihn aufruft, bekommt ihren eigenen unabhängigen State; ein Custom Hook teilt Logik, keine Daten. Siehe Custom Hooks.

Was macht StrictMode?

<StrictMode> schaltet zusätzliche Prüfungen ein, nur in der Entwicklung. Er rendert Komponenten zweimal, um unpures Rendern aufzudecken, führt beim Mounten einmal Setup, Cleanup, Setup der Effekte aus, um fehlende Cleanups aufzudecken, macht dasselbe für Ref-Callbacks und warnt vor veralteten APIs. Nichts davon passiert in einem Produktions-Build, also ist ein doppeltes Konsolen-Log in der Entwicklung zu erwarten und kein Bug.

Fragen für Profis

Was loggt das? (Render, Layout-Effekt, Effekt)

Noch eine Vorhersage. Drei Logs, drei verschiedene Momente in einem Render.

Die Reihenfolge ist Render, dann useLayoutEffect, dann useEffect, obwohl useEffect zuerst geschrieben ist. Layout-Effekte laufen, nachdem React das DOM aktualisiert hat, aber bevor der Browser zeichnet, deshalb eignen sie sich zum Messen eines Elements; normale Effekte laufen später, meist nach dem Zeichnen, und sollten der Standard sein.

Was ist eine Error Boundary?

Eine Klassenkomponente, die Fehler abfängt, die beim Rendern ihrer Kinder geworfen werden, und einen Fallback zeigt, statt die ganze App zu unmounten. Sie braucht static getDerivedStateFromError (um auf den Fallback umzuschalten) und meist componentDidCatch (zum Loggen). Es gibt weiterhin kein Gegenstück als Hook, also schreiben Teams in Codebasen mit Funktionskomponenten eine Klasse oder nutzen das Paket react-error-boundary.

Klicke auf „Break it“: Der Fallback ersetzt nur die Kinder der Boundary, der Button bleibt, und React meldet den abgefangenen Fehler trotzdem in der Konsole. Boundaries fangen keine Fehler in Event-Handlern, in async-Code wie setTimeout oder in der Boundary selbst ab. Dafür nutzt du try/catch und setzt State.

Was ist ein Portal?

createPortal(children, domNode) aus react-dom rendert Kinder in einen anderen DOM-Knoten, typischerweise document.body, und behält sie an derselben Stelle im React-Baum. Modals, Tooltips und Toasts nutzen das, um dem overflow: hidden oder dem Stapelkontext eines Elternteils zu entkommen. Context funktioniert durch ein Portal hindurch, und Events steigen durch den React-Baum auf, also erreicht ein Klick im Portal das onClick des Elternteils, obwohl die DOM-Knoten woanders liegen. Siehe Portals.

Was sind Suspense und lazy?

lazy(() => import('./Chart')) lädt den Code einer Komponente beim ersten Rendern, was dein Bundle aufteilt. <Suspense fallback={<Spinner />}> zeigt den Fallback, solange etwas darin noch lädt: lazy Code oder Daten, die mit use(promise) oder einem Framework mit Suspense-Unterstützung gelesen werden. Wo du Grenzen setzt, entscheidet, welche Teile der Seite gemeinsam warten.

import { lazy, Suspense } from 'react';

const Chart = lazy(() => import('./Chart.jsx'));

export default function Dashboard() {
    return (
        <Suspense fallback={<p>Loading chart...</p>}>
            <Chart />
        </Suspense>
    );
}

Was macht useTransition?

Es markiert ein State-Update als nicht dringend. const [isPending, startTransition] = useTransition() und startTransition(() => setTab('posts')) lassen React den aktuellen Bildschirm reaktionsfähig halten und den langsamen Render unterbrechen, wenn ein dringenderes Update kommt, etwa ein Tastendruck. isPending sagt dir, wann du einen Hinweis zeigen solltest. In React 19 kann die übergebene Funktion async sein, und das nennt React eine Action. Nutze es nicht, um den eigenen Wert eines Texteingabefelds zu aktualisieren; dieses Update muss dringend sein.

Was sind React Server Components?

Komponenten, die nur auf dem Server (oder zur Build-Zeit) laufen und ihr gerendertes Ergebnis an den Browser schicken, nie ihren Code. Sie können async sein und direkt eine Datenbank oder das Dateisystem lesen, aber keinen State, keine Effekte und keine Browser-APIs nutzen. Eine mit 'use client' markierte Datei startet eine Client-Grenze, in der interaktive Komponenten leben, und 'use server' markiert Server-Funktionen, die Client-Code aufrufen kann. Du nutzt sie über ein Framework wie Next.js mit dem App Router; einfache Vite-Apps haben keinen Server, der sie ausführen könnte.

Was hat sich in React 19 geändert?

  • Actions: async-Funktionen in Transitions, bei denen der Pending-Zustand für dich verwaltet wird. Ein <form action={fn}> ruft fn mit den FormData des Formulars auf.
  • Neue Hooks: useActionState für Ergebnis und Pending-Zustand eines Formulars, useOptimistic für optimistische UI und useFormStatus in react-dom.
  • use: liest ein Promise (und suspendiert, bis es aufgelöst ist) oder einen Context und kann anders als andere Hooks in einer Bedingung aufgerufen werden.
  • ref als Prop: Funktionskomponenten erhalten ref wie jede andere Prop, also braucht neuer Code kein forwardRef mehr. Ref-Callbacks können eine Cleanup-Funktion zurückgeben.
  • <Context> als Provider, dazu Tags <title> und <meta>, die in den Head des Dokuments wandern.
  • Entfernt: ReactDOM.render, String-Refs, Legacy Context und defaultProps an Funktionskomponenten (nutze Standardwerte für Parameter).
// React 19: ref is a normal prop
function TextInput({ ref, ...props }) {
    return <input ref={ref} {...props} />;
}

Die Seite zu React 19 hat ausführbare Beispiele für jedes davon.

Wie testet man React-Komponenten?

Mit React Testing Library und einem Runner wie Vitest oder Jest. Du renderst die Komponente, findest Elemente so, wie ein Nutzer es täte (nach Rolle, Label oder Text), interagierst mit user-event und prüfst, was sichtbar ist, nicht den internen State. So bleiben Tests über Refactorings hinweg gültig.

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Counter from './Counter';

test('counts clicks', async () => {
    const user = userEvent.setup();
    render(<Counter />);
    await user.click(screen.getByRole('button', { name: /clicked 0 times/i }));
    expect(screen.getByRole('button')).toHaveTextContent('Clicked 1 times');
});

toHaveTextContent kommt aus @testing-library/jest-dom. Für ganze Abläufe über mehrere Seiten ergänzen Teams Playwright oder Cypress.

Wie findet und behebt man ein Performance-Problem?

Zuerst messen. Öffne den Profiler-Tab in den React DevTools, nimm die langsame Interaktion auf und lies das Flammendiagramm: Es zeigt, welche Komponenten gerendert haben, wie lange jede gebraucht hat und (mit der Einstellung „record why each component rendered“) warum. Typische Lösungen, in der Reihenfolge, in der du sie probieren solltest: State nach unten verschieben, damit weniger Komponenten davon abhängen, langsame Teilbäume als children übergeben, den teuren Teil mit memo, useMemo und useCallback memoisieren, lange Listen virtualisieren und schwere Updates mit useTransition oder useDeferredValue zurückstellen. Profiliere in einem Produktions- oder Profiling-Build; Entwicklungs-Builds sind langsamer und übertreiben Render-Zeiten.

Warum sollte eine Komponente pur sein?

Bei gleichen Props, gleichem State und gleichem Context sollte eine Komponente dasselbe JSX zurückgeben und beim Rendern nichts außerhalb von sich ändern. React kann eine Komponente mehr als einmal rendern, außer der Reihe oder einen Render verwerfen (Transitions, Suspense, StrictMode), also laufen Nebeneffekte im Körper, etwa eine mutierte Variable oder eine gesendete Anfrage, unvorhersehbar oft. Nebeneffekte gehören zuerst in Event-Handler und in Effekte, wenn kein Event sie ausgelöst hat.

Wann solltest du keinen Effekt nutzen?

Wenn der Wert beim Rendern berechnet werden kann (gefilterte Listen, volle Namen, Summen), wenn die Arbeit durch eine Aktion des Nutzers ausgelöst wird (setze sie in den Event-Handler) und wenn du State bei einer Änderung einer Prop zurücksetzen willst (nutze einen key). Effekte sind dafür da, sich mit etwas außerhalb von React zu synchronisieren: einer Netzwerkverbindung, einer Browser-API, einem Widget eines Drittanbieters. Ketten von Effekten, die State setzen, sind eine häufige Quelle für zusätzliche Renders und Bugs.

Häufig gestellte Fragen

Was ist React?

React ist eine JavaScript-Bibliothek, mit der du Benutzeroberflächen aus Komponenten baust. Du beschreibst, wie der Bildschirm für die aktuellen Daten aussehen soll, und React aktualisiert das echte DOM, wenn sich diese Daten ändern.

Was ist der Unterschied zwischen State und Props?

Props sind Eingaben, die ein Elternteil an eine Komponente übergibt, und die Komponente behandelt sie als schreibgeschützt. State sind Daten, die einer Komponente gehören und die sie mit einem Setter im Lauf der Zeit ändert, was React sie erneut rendern lässt.

Was sind Hooks in React?

Hooks sind Funktionen, deren Namen mit use beginnen und mit denen eine Funktionskomponente React-Features nutzt: useState für State, useEffect für Nebeneffekte, useContext für Context, useRef für Werte, die keine Renders auslösen, und mehr.

Was ist das virtuelle DOM?

So nennt man die Beschreibung der UI, die React im Speicher hält. Bei jedem Render baut React eine neue Beschreibung, vergleicht sie mit der vorherigen und wendet nur die Unterschiede auf das echte DOM an. Dieser Vergleich heißt Reconciliation.

Warum sind Keys in React-Listen wichtig?

Ein Key sagt React, welcher Eintrag einer Liste welcher ist, über Renders hinweg. Mit stabilen Keys (etwa einer ID) hält React State und DOM-Knoten jedes Eintrags bei den richtigen Daten, wenn Einträge hinzugefügt, entfernt oder umsortiert werden. Der Array-Index macht das kaputt, sobald sich die Reihenfolge ändert.

Was ist JSX?

JSX ist eine Syntaxerweiterung, mit der du HTML-ähnliches Markup in JavaScript schreibst. Ein Compiler macht aus jedem Tag einen Funktionsaufruf, der ein React-Element erzeugt, also wird <h1>Hi</h1> zu einem einfachen Objekt, das ein h1 beschreibt.

Illustration der Programmiersprachen bei Coddy

Lerne mit Coddy zu programmieren

LOS GEHT'S