Startseite / Artikel / Zwanzig React-Interviewfragen, die zwischen Nutzung und Verständnis unterscheiden

Zwanzig React-Interviewfragen, die zwischen Nutzung und Verständnis unterscheiden

Virtual DOM, Schlüsselwerte, Effekte, Memoisierung, Context, SSR und Hydratation – erläutert mit den tatsächlich gestellten Fragen der Interviewer, nicht mit Lehrbuchdefinitionen.

2102 Wörter

React bereitstellen und React erklären sind unterschiedliche Fähigkeiten. In Interviews wird letzteres geprüft: Was passiert bei setState, warum Schlüssel wichtig sind, wann Effekte erneut ausgeführt werden. Die zwanzig Fragen unten tauchen ständig auf. Die Antworten beziehen sich auf das Problem, das jede Funktion löst, sowie auf die Fallstricke in der Produktion – nicht auf auswendig gelernte Formeln.

1. Was der Virtuelle DOM tatsächlich ist

Der Virtuelle DOM ist kein magisches Beschleunigungsmittel. Es handelt sich dabei um einen gewöhnlichen JavaScript- Baum, der beschreibt, wie die Benutzeroberfläche aussehen sollte. Bei einem Zustandswechsel erstellt React einen neuen virtuellen Baum, vergleicht ihn mit dem vorherigen und vereinbart die Unterschiede, indem nur die notwendigen Änderungen am Browser- DOM vorgenommen werden. Reale DOM-Arbeiten lösen Layout- und Zeichnungsprozesse aus; das Ändern von JavaScript-Objekten ist kostengünstig, weshalb React die CPU im Speicher nutzt, um den Browser möglichst wenig zu belasten. Dieses Design zielt darauf ab, die Belastung des Browsers zu minimieren – nicht darauf, jede Vergleichsoperation kostenlos zu machen. Zu behaupten, „der Virtuelle DOM sei immer schneller“, ohne diese Nuancen zu berücksichtigen, ist eine häufige Falle für Anfänger.

2. Virtueller DOM gegenüber dem Browser- DOM

Reale DOM-Änderungen sind aufwändig und können zum Neustrukturieren sowie Neuzeichnen des Inhalts führen. Virtuelle Updates sind hingegen Unterschiede von Objekten im Speicher; React gruppiert teure DOM-Einschreibungen, anstatt pro Zustandsaufruf einmal zu handeln. Das Bearbeiten mit track-changes ist effektiver als das Neuverfassen des gesamten Dokuments bei jedem Tippfehler.

3. Warum Schlüssel wichtig sind, wenn Zeilen verschoben werden

Schlüssel identifizieren Elemente über mehrere Renderungen hinweg. Ohne sie greift React auf die Indexposition zurück, was fehlschlägt, wenn Elemente eingefügt, gelöscht oder umgeordnet werden. Die Verwendung des Array-Index als Schlüssel „funktioniert“ zwar, führt aber bei Umordnungen dazu, dass Eingabefelder und Kontrollkästchen den falschen Zeilen zugeordnet werden – ein sogenannter „Zustandsleck“, der in Wirklichkeit auf einen Schlüsselfehler zurückzuführen ist. Verwenden Sie stattdessen stabile, eindeutige IDs aus den Daten; Indexe eignen sich nur für wirklich statische Listen. Wenn das Produkt eine Umordnung per Drag-and-Drop oder Filterfunktionen ermöglicht, führen Indexe als Schlüssel letztendlich zu Fehlern im zeilenbezogenen Zustand.

4. Erklärung von useState aus den Grundprinzipien heraus

Normale Benutzer sterben, wenn eine Funktion zurückgegeben wird. useState verleiht einem Funktionskomponenten dauerhaften Speicher und plant eine Neugenerierung, wenn sich dieser Speicher ändert:

const [count, setCount] = useState(0);

count ist der aktuelle Wert; setCount beantragt eine Aktualisierung. Die Aktualisierung wird nicht mitten in der Generierung angewendet: Das Ausgeben von count unmittelbar nach setCount zeigt weiterhin den vorherigen Wert, da der neue Wert bei der nächsten Generierung sichtbar wird.

5. Warum useState-Updates verzögert oder gebündelt erscheinen

React bündelt Updates, die im selben Ereignis anfallen, zu einer einzigen Neugenerierung. Seit React 18 umfasst dieses Bündeln auch Promises und Timer, nicht nur React-Ereignishandler. Wenn Sie den neuesten Wert auf der Grundlage des vorherigen Zustands benötigen, verwenden Sie den funktionalen Aktualisierer:

setCount(prev => prev + 1);

Dieses Formular verwendet den aktuellsten im Warteschlangen-Status befindlichen Wert anstelle eines veralteten Snapshots der Schließfunktion. Interviewer fragen oft nach, was passiert, wenn man innerhalb einer Zeitüberschreitung über count schließt, ohne das Aktualisierungsformular zu verwenden.

6. Welches Problem löst useEffect eigentlich?

Das Rendern sollte eine reine Funktion von Props und State zu JSX sein. Apps holen außerdem Daten ab, fügen Ereignislistener hinzu, planen Timer ein und greifen auf den DOM zu – das sind Nebeneffekte. useEffect führt diese unreinen Aufgaben nach dem Commit aus, nicht während des Renderns:

useEffect(() => {
  const id = setInterval(() => console.log("tick"), 1000);
  return () => clearInterval(id); // cleanup
}, []);

Die zurückgegebene Cleanup-Funktion wird vor dem nächsten Effect sowie beim Entfernen der Komponente ausgeführt. Wenn man sie weglässt, fragen Interviewer nach doppelten Timern und leckenden Listenern, die auch nach dem Entfernen weiterhin ausgelöst werden.

7. Was steuert eigentlich der Abhängigkeitsarray?

Er teilt React mit, wann der Effect über flache Vergleiche erneut ausgeführt werden soll:

  • [] — einmal nach dem Mount
  • [count] — erneut, wenn sich count ändert
  • nicht angegeben — nach jeder Renderung (selten gewünscht)

Vergisst man einen in der Array referenzierten Wert, entsteht eine veraltete Schließung: Der Effekt behält den ursprünglich erfassten Wert für immer bei. Es gibt ausführliche Lint-Regeln für solche Fälle, weil diese Art von Fehler sehr häufig vorkommt.

8. Kontrollierte vs. unkontrollierte Komponenten

Kontrollierte Eingabefelder beziehen ihren value aus dem React-State und aktualisieren sich über onChange; React besitzt die Wahrheit.

Unkontrollierte Eingabefelder behalten den DOM-Status bei; dieser wird bei Bedarf über ref abgerufen (oft beim Absenden).

// Controlled
<input value={name} onChange={e => setName(e.target.value)} />
// Uncontrolled
<input ref={inputRef} defaultValue="Dev" />

Die kontrollierte Variante ermöglicht eine Echtzeit-Validierung und -Formatierung, kostet aber eine Neulayoutung bei jeder Tastenbetätigung. Die unkontrollierte Variante bleibt leichter, wenn nur der endgültige Wert benötigt wird. Gemischte Formulare – bei denen einige Felder kontrolliert und andere nicht – sind möglich, erweisen sich aber in Überprüfungen als schwieriger zu verstehen.

9. Prop-Drilling und wann man aufhören sollte

Prop-Drilling leitet Daten durch Schichten weiter, die diese lediglich weiterleiten. Umbenennungen betreffen viele Dateien. Context ist hilfreich bei Themen, Authentifizierung oder Lokalisierung; Redux oder Zustand kommen zum Einsatz, wenn die Zustandsgraphen komplex werden. Nuance: Context ist nicht kostenlos – jeder Verbraucher lädt neu, wenn sich der Wert ändert – daher eignet er sich nicht standardmäßig für jedes gemeinsam genutzte Feld. Das Übergeben von Props über zwei Ebenen ist oft klarer als das Erfinden eines Context-Providers für einen einmaligen Wert.

10. Wann sollte man useReducer statt useState verwenden?

Nutzen Sie useReducer, wenn die Aktualisierungen je nach Aktionstyp unterschiedlich verlaufen, der nächste Zustand auf komplexe Weise vom vorherigen Zustand abhängt oder mehrere Felder gleichzeitig geändert werden:

function reducer(state, action) {
  switch (action.type) {
    case "increment": return { count: state.count + 1 };
    case "reset": return { count: 0 };
    default: return state;
  }
}
const [state, dispatch] = useReducer(reducer, { count: 0 });

Es handelt sich dabei um eine Art Mini-Redux innerhalb der Komponente. Ein boolescher Schalter wird mit useState verwaltet; verschachtelte Übergangslogiken gehören in einen testbaren Reducer. Durch den Verzicht auf solche Logiken in den JSX-Event-Handlern werden Unit-Tests ohne Renderen des gesamten Baums viel einfacher.

11. Erklären Sie useMemo vs useCallback, anstatt nur die Dokumentation wiedergeben zu wollen

Sowohl Funktionen vermeiden überflüssige Berechnungen bei verschiedenen Datentypen zwischen den Render-Vorgängen:

  • useMemo speichert einen berechneten Wert
  • useCallback speichert eine Funktionreferenz
const sorted = useMemo(() => expensiveSort(list), [list]);
const handleClick = useCallback(() => doThing(id), [id]);

Die Funktionsidentität ist wichtig, denn jede Neuzeichnung erzeugt ein neues Funktionsobjekt. Das Übergeben einer neuen Funktion an ein memo-Kind untergräbt diese Memoisierung; useCallback hält die Referenz stabil. Verwenden Sie weder das eine noch das andere Hook überall – Memoisierung hat ihren Preis. Nutzen Sie sie für aufwändige Operationen oder memoisierte Kinderkomponenten. Frühzeitige Memoisierung ist ein häufiger Fehler bei Junior-Entwicklern, den Interviewer gerne ansprechen.

12. React.memo ist nützlich – und leicht zu umgehen

React.memo überspringt eine Neuzeichnung, wenn die Props oberflächlich gleich sind. Neue Objekt- oder Array-Literale gelten als unterschiedlich, selbst wenn ihr Inhalt identisch ist; daher macht { style: { color: 'red' } } memo nutzlos, es sei denn, die Elternkomponenten stabilisieren die Props mit useMemo/useCallback. Andernfalls verursacht memo zusätzliche Vergleichskosten, ohne die Arbeit der Kindkomponente zu verhindern.

13. Schlüssel als Identität, nicht nur ein Konsole-Warnhinweis

Schlüssel bilden Reacts Identitätsystem zwischen den Renderungen. Falsche Schlüssel führen dazu, dass für falsche Daten derselbe DOM-Node wiederverwendet wird: Der Formzustand bleibt an einer anderen Zeile haften, Animationen werden am falschen Element ausgelöst und der useState-Zustand eines List-Items behält den Wert des vorherigen Elements bei. Es sieht aus wie ein Zustandsfehler – in Wirklichkeit handelt es sich um einen Fehler mit den Schlüsseln. Die Darstellung einer fehlerhaften index-key-Liste in einem Sandbox ist eine der schnellsten Methoden, sich diese Regel einzuprägen.

14. Context: richtige und falsche Anwendungen

Context teilt Werte, die viele Komponenten benötigen, ohne Prop-Verbindungen – z. B. angemeldeter Benutzer, Theme, Lokalisation:

const ThemeContext = createContext();
<ThemeContext.Provider value={theme}>
  <App />
</ThemeContext.Provider>

Es eignet sich schlecht für hochfrequente Zustände (Wertänderungen pro Tastendruck) in großen Strukturen, da jeder Verbraucher bei jeder Änderung aktualisiert wird, ohne dass es eine selektive Abonnementsmöglichkeit gibt. Für solche Fälle sollte man einen Speicher mit feinerer Abonnementsstruktur verwenden. Themenschalter sind ein klassisches Beispiel für einen guten Kontextpassungsfaktor; Cursorpositionen in einem gemeinsam genutzten Editor hingegen meist nicht.

15. Zuordnung von Klassenlebenszyklen zu Effekten

Grobe Zuordnung der Klassen:

  • componentDidMount → useEffect(..., [])
  • componentDidUpdate → useEffect(..., [dep])
  • componentWillUnmount → Effektreinigung

Der tiefere Wandel: Lebenszyklen denken in Zeit (Hochladen/Update/Abschalten); Effekte denken in Synchronisierung – dieses externe System muss mit diesen Werten übereinstimmen – weshalb Effekte erneut ausgeführt werden, wenn sich Abhängigkeiten ändern. Wenn man Effekte als line-for-line übersetzte Lebenszyklusmethoden behandelt, gerät man unweigerlich in Konflikte mit dem Abhängigkeitsarray.

16. Zustand im Vergleich zu Props

Props sind nur zum Lesen bestimmte Eingaben von einem Elternteil. Zustand ist das eigene Datenmaterial, das bei Veränderung eine erneute Darstellung auslöst. Props konfigurieren ein Komponente von außen; Zustand ist das, was die Komponente über sich selbst speichert. Der Label einer Schaltfläche ist ein Prop; ob sie während eines laufenden Anfrages deaktiviert ist, gehört zum Zustand. Die Verwechslung beider führt zu Anti-Patterns wie dem Versuch, Props zu verändern, oder dem Zu hoch ansetzen von vorübergehenden UI-Flags.

17. Unnötige erneute Darstellungen ohne Raten finden

Häufige Ursachen: Eltern übergeben neue Objekt-/Array-/Funktion-Literale, Context-Änderungen führen zur Neugenerierung aller Nutzerkomponenten, oder der Zustand befindet sich auf einer zu hohen Ebene. Raten Sie nicht – verwenden Sie den React DevTools Profiler, erfassen Sie eine Interaktion und prüfen Sie, welche Props sich geändert haben. Lösungen bestehen oft darin, den Zustand nach unten zu verschieben oder Komponenten aufzuteilen, damit teure Unterbäume nicht mit billigen Updates übertragen werden, anstatt zunächst useMemo zu verwenden. Profiler verwandeln das Gefühl von Langsamkeit in eine konkrete Erklärung bezüglich Elternkomponenten und Props, die Sie beheben können.

18. SSR im Vergleich zu CSR

CSR liefert eine schlanke HTML-Struktur zusammen mit JS; der Browser erstellt die Seite nach dem Herunterladen – schnell zur Bereitstellung, langsamer beim sichtbaren Anzeigen der Inhalte, historisch gesehen schwächer in Bezug auf SEO, bis JS ausgeführt wird. SSR sendet bei jeder Anfrage HTML und fügt anschließend durch das Hinzufügen von Listenern die dynamischen Elemente hinzu – besseres erstes Anzeigen der Seite und bessere SEO-Ergebnisse, aber mehr Serverarbeit. Next.js und ähnliche Frameworks bieten zusätzlich die statische Generierung sowie Streaming an, doch das grundlegende Abwägungsproblem bleibt weiterhin TTFB/SEO gegenüber den Serverkosten und der Komplexität. Zu behaupten, „SSR sei immer besser“, ohne dieses Abwägungsproblem zu nennen, ist eine schwache Antwort in einem Vorstellungsgespräch.

19. Unterschiede bei der Hydratierung und wie sie entstehen

Hydration verknüpft React mit dem Server-HTML, ohne die Markup-Struktur zu vernichten. Unstimmigkeiten entstehen, wenn das Server-HTML von der ersten Darstellung am Client abweicht: Date.now() oder Math.random() werden bei der Darstellung verwendet, während window-Prüfungen auf dem Server anders ausfallen, oder Erweiterungen fügen Nodes hinzu. React warnt lautstark und lädt den Client häufig neu, um wieder in Ordnung zu bringen – was zusätzliche Arbeit sowie einen sichtbaren Aufblitzen von fehlerhaftem Inhalt verursacht. Die übliche präventive Vorgehensweise besteht darin, browserexklusive APIs hinter useEffect oder Feature-Components zu verbergen.

20. Warum React native Events in SyntheticEvent einhüllt

React’s SyntheticEvent normalisiert abweichendes Verhalten verschiedener Browser (damit onChange konsequent funktioniert) und nutzte ursprünglich die Delegation von Ereignissen auf der Wurzelebene anstelle eines nativen Listeners pro Knoten. In React 17+ wird die Delegation an den Wurzelcontainer der Anwendung statt an document vorgenommen, doch das Konzept bleibt gleich. Früher wurden Ereignisobjekte gepoolt, um sie wiederverwenden zu können, sodass asynchrone Zugriffe manchmal null zurücklieferten; seit React 17 gibt es kein Pooling mehr, doch das Wissen über die Schicht zwischen dem Browser-Ereignis und dem Handler gibt weiterhin Aufschluss über die Tiefe. Die Erwähnung, dass e.nativeEvent weiterhin vorhanden ist, zeigt, dass man versteht, dass es sich bei der Abstraktion um eine Hülle handelt und nicht um einen Ersatz für das DOM-Ereignismodell.

Was bei Vorstellungsgesprächen tatsächlich gewürdigt wird

Kraftvolle Antworten in einem Vorstellungsgespräch erläutern das Problem, die Schwierigkeiten sowie wie man einen Teamkollegen wieder in Gang bringen könnte – und nicht nur eine auswendig gelernte Definition. Die Interviewer interessieren sich weniger dafür, ob man useEffect definieren kann, sondern vielmehr dafür, ob veraltete Schließfunktionen, fehlende Aufräumarbeiten oder Abhängigkeitsfehler zu Problemen geführt haben und ob man erklären kann, warum. Reproduzieren Sie diese Fehler in einer Sandbox vor dem Gespräch; praktische Erfahrungen zeigen Verständnis. Definitionen helfen nur, die erste Minute zu überstehen; Abwägungen und Erfolgsgeschichten bestimmen den weiteren Verlauf des Gesprächs.

Halten Sie ein kurzes persönliches CheatSheet mit den Fehlern, die Sie behoben haben – veraltete Effekte, fehlerhafte Tastenkombinationen, Unstimmigkeiten bei der Hydratation – und üben Sie darin, jeden Fehler in weniger als einer Minute zu erklären. Diese Vorbereitung ist besser als das Auswendiglernen von API-Signaturen in der Nacht zuvor und liefert konkrete Beispiele, wenn ein Interviewer nach einem Beispiel aus Ihrer Arbeit fragt. Verbinden Sie jedes Beispiel mit der von Ihnen implementierten Lösung, damit die Antwort auf Urteilsfähigkeit statt nur auf Schwierigkeiten beruht. Genau dieser Schlusspunkt unterscheidet diejenigen, die nur die Dokumentation lesen, von denen, die diese Technologien unter Druck einsetzen können.