Was er wirklich prüft (und warum er nervt)
React StrictMode ist kein optionaler Komfort — er ist ein Frühwarnsystem für Bugs, die in Production still und tückisch fehlschlagen. Warum er Components zweifach rendert, useEffect doppelt feuert und was das mit Concurrent Features zu tun hat.
Inhaltsverzeichnis
- 1. Was React Strict Mode wirklich ist
- 2. Warum Components zweimal gerendert werden
- 3. useEffect: doppelter Mount in React 18+
- 4. Deprecated APIs erkennen
- 5. Strict Mode und Concurrent Features
- 6. Unerwünschte Side-Effects aufdecken
- 7. Strict Mode in der Praxis: typische Fehlerbilder
- 8. Mit und ohne Strict Mode im Vergleich
- 9. Neu in React 19: verschärfte Checks
- 10. Zusammenfassung
- 11. FAQ
1. Was React Strict Mode wirklich ist
Der React Strict Mode ist ein Development-only-Wrapper, der keine visuellen Änderungen an der Anwendung vornimmt, aber gezielt Verhaltensprüfungen aktiviert, die in Production deaktiviert sind. Er wird typischerweise in der Wurzel der Anwendung gesetzt, kann aber auch selektiv um einzelne Teilbäume gelegt werden. Das Ziel ist nicht, Code strenger zu schreiben — es geht darum, Bugs sichtbar zu machen, die ohne StrictMode erst in der Production mit echten Nutzern auftreten.
Entwickler erleben StrictMode oft als störend, weil er Konsolen-Warnings produziert und Effekte mehrfach ausführt. Aber das ist der Punkt: Jedes dieser unerwarteten Verhaltensweisen ist ein Symptom eines echten Problems in der Komponente. Wer StrictMode abschaltet, um die Konsole ruhig zu halten, versteckt Bugs — er behebt sie nicht. Der React Strict Mode ist daher eines der effektivsten kostenlosen Debugging-Werkzeuge, das React mitliefert.
React aktiviert den StrictMode automatisch in neuen Projekten, die mit create-react-app oder Vite initialisiert werden. In bestehenden Projekten lässt er sich granular einsetzen: <React.StrictMode> kann gezielt nur um problematische Modulbereiche gelegt werden, um den Migrationsaufwand zu steuern.
2. Warum Components zweimal gerendert werden
Das auffälligste Verhalten des React Strict Mode ist das doppelte Rendering von Komponenten im Development-Modus. React ruft Render-Funktionen, Initializer von useState, Reducer-Funktionen und Lazy Initializer zweimal auf — aber zeigt nur das Ergebnis des zweiten Durchlaufs an. Das klingt nach einem Fehler, ist aber absichtlich: Es soll sicherstellen, dass Render-Funktionen keine Side-Effects haben.
Eine reine Render-Funktion produziert bei gleichen Eingaben immer dieselbe Ausgabe. Wenn der zweite Render-Durchlauf ein anderes Ergebnis liefert als der erste — oder wenn globale Zustände, externe Variablen oder API-Aufrufe darin stattfinden — hat die Komponente einen unzulässigen Side-Effect im Render-Pfad. In React 18 mit Concurrent Features kann React Render-Vorgänge unterbrechen, pausieren und neu starten. Wenn eine Komponente beim Neustart einen anderen Zustand hat, entstehen schwer reproduzierbare Bugs in Production.
// Example: impure render function — StrictMode exposes this bug
let renderCount = 0;
function ImpureCounter() {
// WRONG: side effect in render body — increments on every render call
renderCount++;
return <div>Renders: {renderCount}</div>;
// In StrictMode: displays 2, not 1 — exposes the mutation
}
// CORRECT: side effects belong in useEffect, never in render
function PureCounter() {
const [count, setCount] = React.useState(0);
// render body is pure — same props/state always yield same output
return <div>Count: {count}</div>;
}
// WRONG: lazy initializer with side effect
const [value] = React.useState(() => {
fetch('/api/init').then(r => r.json()).then(setData); // side effect!
return 0;
});
// CORRECT: fetch in useEffect, not in initializer
React.useEffect(() => {
fetch('/api/init').then(r => r.json()).then(setData);
}, []);
3. useEffect: doppelter Mount in React 18+
Ab React 18 führt der React Strict Mode einen zusätzlichen Check ein, der speziell auf useEffect abzielt: Jede Komponente wird einmal gemountet, dann unmounted und sofort wieder gemountet. Das bedeutet, dass useEffect-Callbacks im Development-Modus zweimal ausgeführt werden — mit dem vollständigen Mount-Unmount-Zyklus dazwischen. React simuliert damit das Verhalten von Future React, das Komponenten für Features wie Offscreen-Rendering ausblenden und wiederherstellen kann.
Der Remount-Check deckt fehlende Cleanup-Funktionen in useEffect auf. Wenn ein Effekt eine WebSocket-Verbindung öffnet, ein Intervall startet oder einen Event-Listener registriert, muss die zurückgegebene Cleanup-Funktion diese Ressource wieder freigeben. Ohne Cleanup führt der doppelte Remount zu zwei offenen Verbindungen, zwei laufenden Intervallen oder zwei Event-Listenern — ein direktes Abbild dessen, was in Production passiert, wenn React Concurrent Features Komponenten aus- und wieder einblendet.
// WRONG: no cleanup — in StrictMode this fires twice, leaving two intervals
React.useEffect(() => {
const id = setInterval(() => {
setTick(t => t + 1);
}, 1000);
// missing: return () => clearInterval(id);
}, []);
// CORRECT: cleanup function cancels the interval on unmount
React.useEffect(() => {
const id = setInterval(() => {
setTick(t => t + 1);
}, 1000);
return () => clearInterval(id); // runs on unmount and before re-run
}, []);
// CORRECT: WebSocket with full cleanup
React.useEffect(() => {
const ws = new WebSocket('wss://api.mironsoft.de/live');
ws.addEventListener('message', handleMessage);
return () => {
ws.removeEventListener('message', handleMessage);
ws.close();
};
}, []);
// CORRECT: AbortController pattern for fetch
React.useEffect(() => {
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then(r => r.json())
.then(setData)
.catch(err => { if (err.name !== 'AbortError') throw err; });
return () => controller.abort();
}, []);
4. Deprecated APIs erkennen
Der React Strict Mode gibt Konsolen-Warnings aus, wenn deprecated APIs verwendet werden. In älteren React-Versionen betraf das componentWillMount, componentWillReceiveProps und componentWillUpdate — die sogenannten Legacy-Lifecycle-Methoden, die in Concurrent React zu Problemen führen, weil sie mehrfach aufgerufen werden können, bevor ein Render abgeschlossen ist. Diese Methoden wurden mit dem Präfix UNSAFE_ versehen und produzieren im Strict Mode eine deutliche Warnung.
In modernen React-Projekten ist das primäre Ziel der API-Prüfung: veraltete String-Refs (ref="myRef") und die Legacy Context API zu erkennen. Die Legacy Context API mit childContextTypes und contextTypes ist seit React 16 deprecated und in React 19 entfernt. Wer Drittbibliotheken verwendet, die noch Legacy-Context nutzen, bekommt durch StrictMode Hinweise auf zukünftige Kompatibilitätsprobleme — lange bevor die nächste Major-Version diese APIs entfernt.
5. Strict Mode und Concurrent Features
Der React Strict Mode ist untrennbar mit dem Concurrent-Rendering-Modell von React 18 und 19 verbunden. Concurrent React kann Renders unterbrechen, in mehreren Phasen ausführen und Prioritäten vergeben. Das Modell funktioniert korrekt nur, wenn Komponenten bestimmte Invarianten einhalten: Render-Funktionen müssen idempotent sein, State-Updates dürfen keine externen Abhängigkeiten haben, und Effekte müssen sauber aufgeräumt werden. StrictMode prüft genau diese Invarianten im Development-Modus.
Ohne StrictMode kann eine Anwendung jahrelang mit subtilen Verletzungen dieser Invarianten laufen — weil React synchronous-Rendering keine dieser Regeln erzwingt. Sobald aber Transitions (useTransition), Deferred Values (useDeferredValue) oder Suspense mit parallelen Requests eingesetzt werden, treten die latenten Bugs als sporadische Fehler in Production auf. StrictMode macht diese Fehler früh reproduzierbar, statt sie erst in Production mit echten Usern zu entdecken.
6. Unerwünschte Side-Effects aufdecken
Neben dem doppelten Rendering prüft der React Strict Mode gezielt auf Side-Effects in Positionen, in denen React sie nicht erwartet. Dazu gehören der Körper von Komponenten-Funktionen, die Initialisierungsfunktion von useState, Reducer-Funktionen in useReducer, und der Selector in useMemo. In all diesen Positionen gilt: dieselbe Eingabe muss immer dieselbe Ausgabe produzieren, ohne externe Systeme zu verändern.
Ein klassischer Fehler in der Praxis: eine Komponente schreibt beim Rendern in eine externe Variable oder ruft einen Analytics-Tracker auf. In Production wird die Seite einmal gerendert — alles sieht korrekt aus. Mit StrictMode wird dasselbe Event zweimal gefeuert, was zu doppelten Analytics-Einträgen führt. Das ist der Punkt, an dem das Team merkt, dass der Analytics-Aufruf in einen Effekt gehört, nicht in den Render-Body. Genau für diese Erkenntnis ist StrictMode gebaut.
7. Strict Mode in der Praxis: typische Fehlerbilder
Im Alltag zeigen sich bestimmte Fehlermuster immer wieder, wenn Teams zum ersten Mal React Strict Mode aktivieren oder auf React 18 upgraden. Das häufigste: API-Requests werden doppelt gefeuert. Statt StrictMode zu deaktivieren, ist die korrekte Lösung ein AbortController in der Cleanup-Funktion oder eine Deduplizierung auf Bibliotheks-Ebene (React Query, SWR, Apollo). Ein zweites Muster: Event-Listener häufen sich, weil kein Cleanup implementiert ist — nach einigen Navigationen in einer SPA reagiert die Anwendung mehrfach auf jedes Event.
Ein drittes häufiges Fehlerbild betrifft externe Stores und Subscriptions. Wenn eine Komponente in useEffect einen Redux-Store oder einen externen Event-Emitter abonniert, ohne das Abonnement in der Cleanup-Funktion zu kündigen, entstehen Memory Leaks und doppelte Verarbeitung. StrictMode macht diesen Fehler durch den erzwungenen Remount sofort reproduzierbar — im Gegensatz zu Production, wo der Fehler erst nach langen Sessions auftritt und schwer reproduzierbar ist.
8. Mit und ohne Strict Mode im Vergleich
Der Unterschied zwischen Entwicklung mit und ohne React Strict Mode zeigt sich am deutlichsten bei der Bug-Dichte in Production. Teams, die StrictMode konsequent nutzen und alle Warnings ernst nehmen, berichten von signifikant weniger sporadischen, schwer reproduzierbaren Fehlern in Produktionssystemen.
| Verhalten | Ohne Strict Mode | Mit Strict Mode | Vorteil |
|---|---|---|---|
| Render-Aufrufe | Einmal pro State-Änderung | Zweimal (nur Dev) | Impure Renders sofort sichtbar |
| useEffect-Aufrufe | Einmal nach Mount | Mount → Unmount → Mount | Fehlende Cleanups sofort erkennbar |
| Deprecated APIs | Keine Warnung | Console Warning | Migration vor Breaking Change |
| Concurrent-Bugs | Erst in Production sichtbar | In Dev reproduzierbar | Früher gefunden, günstiger behoben |
| Memory Leaks | Nach langen Sessions | Sofort nach Remount | Stabile Long-Running-SPAs |
9. Neu in React 19: verschärfte Checks
React 19 verschärft den React Strict Mode in mehreren Punkten. Der auffälligste: React 19 gibt Warnungen aus, wenn Refs direkt auf DOM-Elemente mit findDOMNode zugegriffen werden — eine API, die in React 19 entfernt wurde. Teams, die StrictMode ab React 18 konsequent genutzt haben, haben diese Migrationsarbeit bereits erledigt. Wer StrictMode übersprungen hat, findet sich bei einem React-19-Upgrade vor einer langen Liste von Breaking Changes.
Ein weiterer neuer Check in React 19 betrifft den Hydration-Prozess: StrictMode prüft, ob Server- und Client-Rendering identische Ergebnisse liefern. Abweichungen — etwa durch Zeitstempel, zufällige IDs oder Browser-spezifische Informationen im initialen Render — werden als Hydration-Mismatch-Warnungen ausgegeben. In Server Components und Next.js-Projekten ist dieser Check besonders wertvoll, weil Hydration-Probleme in Production zu subtilen Layout-Flickers oder fehlerhafter Interaktivität führen.
// React 19: StrictMode checks for ref usage patterns
// WRONG: findDOMNode is removed in React 19
class OldComponent extends React.Component {
handleClick() {
const node = ReactDOM.findDOMNode(this); // removed in React 19!
node.scrollIntoView();
}
}
// CORRECT: use ref forwarding
const NewComponent = React.forwardRef(function NewComponent(props, ref) {
return <div ref={ref} onClick={() => ref.current?.scrollIntoView()}>...</div>;
});
// React 19 StrictMode: hydration mismatch detection
// WRONG: non-deterministic output in render
function Timestamp() {
return <span>{new Date().toLocaleString()}</span>; // differs server vs client!
}
// CORRECT: use useEffect for client-only values
function Timestamp() {
const [time, setTime] = React.useState<string | null>(null);
React.useEffect(() => {
setTime(new Date().toLocaleString());
}, []);
return <span>{time ?? '—'}</span>;
}
10. Zusammenfassung
Der React Strict Mode ist kein optionaler Quality-of-Life-Feature — er ist ein systematisches Frühwarnsystem für drei Klassen von Fehlern: impure Render-Funktionen, fehlende Effect-Cleanups und deprecated APIs. Das doppelte Rendering und der erzwungene Remount im Development-Modus sind keine Bugs in React, sondern gezielte Werkzeuge, um Probleme sichtbar zu machen, die in Production mit Concurrent Features stille, schwer reproduzierbare Fehler verursachen.
Teams, die StrictMode aktivieren und konsequent alle Warnings beheben, investieren in die langfristige Stabilität ihrer Anwendung. Das gilt besonders für Projekte, die auf React 18 oder 19 migrieren oder Concurrent Features wie useTransition, Suspense oder Server Components einsetzen. StrictMode ist der einzige Development-Mechanismus, der diese Bugs reproduzierbar macht, bevor sie in Production echte Nutzer treffen.
React Strict Mode — Das Wichtigste auf einen Blick
Doppelte Renders
Render-Funktionen werden zweimal aufgerufen, um impure Render-Bodies zu entdecken. Nur Dev-Modus — Production ist unberührt.
Effect-Remounts
useEffect feuert Mount → Unmount → Mount, um fehlende Cleanup-Funktionen sichtbar zu machen. Ab React 18.
Deprecated APIs
Legacy-Lifecycles, String-Refs und Legacy-Context erzeugen Konsolen-Warnings — als Vorwarnung vor Breaking Changes in der nächsten Major-Version.
Concurrent-Readiness
StrictMode prüft die Invarianten, die Concurrent Features wie useTransition und Suspense voraussetzen. Unverzichtbar vor React-18/19-Migration.
Mironsoft
React-Architektur, Performance-Optimierung und Migration auf React 18/19
React-Anwendung auf Concurrent-Ready upgraden?
Wir analysieren bestehende React-Codebases auf StrictMode-Probleme, beheben fehlende Cleanups und begleiten die Migration auf React 18 und 19 — mit vollständiger Concurrent-Kompatibilität.
Code-Audit
StrictMode-Analyse, fehlende Cleanups und impure Renders systematisch aufdecken
Migration
Upgrade auf React 18/19 mit Concurrent Features und vollständiger StrictMode-Compliance
Schulung
Team-Workshops zu Concurrent React, Effect-Cleanup-Patterns und StrictMode-Debugging