Startseite / Artikel / Praktische Hinweise: React-Komponenten müssen rein sein – das Geheimnis hinter StrictMode

Praktische Hinweise: React-Komponenten müssen rein sein – das Geheimnis hinter StrictMode

Schritt-für-Schritt-Anleitung zu den Praktischen Hinweisen: React-Komponenten müssen rein sein – das Geheimnis hinter StrictMode: Verträge, Überprüfungen sowie Code-Plätze für Teams, die dieses Muster einsetzen.

1954 Wörter

Nutzen Sie dies als für Entwickler zugängliche Neuformulierung der Ideen aus „React Components Must Be Pure — the Secret Behind StrictMode and the Compiler“: klare Phasen, geordnete Codeabschnitte sowie Notizen zur Wiederherstellung, die auch bei Übergaben erhalten bleiben. Die Überblicksphase funktioniert am besten, wenn sie als messbarer Rahmen betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs eine „goldene“ Transkription, einen Fehlerfall sowie die Notizen zur Rücksetzung. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab.

Was ist eine reine Funktion?

Für die Phase „Was ist eine reine Funktion?“ sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Erhalten Sie neben den funktionalen Ergebnissen auch Aufzeichnungen der Laufzeiten sowie der Kosten für Tokens oder Abfragen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Weg von einer Demo-Umgebung in gemeinsam genutzte Umgebungen wechselt. Platzieren Sie den Zustand zusammen mit dem Komponenten, der die Mutation verantwortet. Wenn alles in einem globalen Speicher abgelegt wird, fällt es schwerer, Fehler bezüglich der Laufzeiten zu erkennen.

// ✅ pure function — same input, same output, and it touches nothing outside
function double(x: number): number {
  return x * 2;
}
double(3); // 6
double(3); // 6 — six no matter how many times you call it

// 🔴 impure function — it changes the outer variable `total` (a side effect)
let total = 0;
function addToTotal(x: number): number {
  total += x;     // side effect!
  return total;   // the result changes on every call
}
addToTotal(3); // 3
addToTotal(3); // 6 — same input, different result

Auch eine Komponente ist eine reine Funktion

Für den A-Komponenten, der eine Phase darstellt, sollten Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckten Zustände schließen zu müssen. Die Konfiguration sollte außerhalb des Anwendungscode gespeichert werden. Umgebungsdateien, Geheimdatenspeicher sowie Feature-Flags sollten an einem Ort zusammengefasst sein, den Operator:innen überprüfen können, ohne den gesamten Ablauf durchlesen zu müssen. Der Zustand sollte zusammen mit der Komponente gespeichert werden, die die Mutation verantwortet. Das Zusammenfassen aller Daten in einem globalen Speicher erschwert das Erkennen von Zeitproblemen.

type Props = { name: string };

// ✅ pure — same name, always the same result
function Greeting({ name }: Props) {
  return <h1>Hello, {name}!</h1>;
}

Die Regel brechen – während der Darstellung nichts von außen anfassen

Für die Break the Rule Don-Phase sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Codeändern definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Notfallweg. Wiederholungsversuche, menschliche Überprüfungen und die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Platzieren Sie den Zustand zusammen mit dem Komponenten, der für die Änderung verantwortlich ist. Das Hinzufügen aller Daten in einen globalen Speicher erschwert das Erkennen von Zeitproblemen. Für die Break the Rule Don-Phase sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Codeändern definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Ergebnisdokumente, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab.

let count = 0; // a variable outside the component

// 🔴 not pure — changes an external variable while rendering
function Counter() {
  count = count + 1; // side effect!
  return <p>{count}</p>;
}

Erstellen Sie es selbst – Warum erscheint „2“?

Wenn Sie die Phase „Erstellen Sie es selbst – Warum“ durchlaufen, notieren Sie zunächst den Vertrag: erforderliche Eingaben, Erfolgsignal sowie was bei teilweisen Fehlern geschieht. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Notieren Sie die Laufzeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Weg von einer Demo zu gemeinsam genutzten Umgebungen wechselt. Betrachten Sie Auswirkungen als Synchronisierung mit der Außenwelt und nicht als Ersatz für während des Renderns erzeugte Werte.

import { useState } from 'react';

let count = 0;

function Counter() {
  const [, setTick] = useState(0); // a device to trigger re-renders
  count = count + 1; // 🔴 changes an external variable on every render
  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setTick((n) => n + 1)}>Re-render</button>
    </div>
  );
}
// ✅ pure — computed from input (props) alone
function Counter({ count }: { count: number }) {
  return <p>{count}</p>;
}

Aber Sie können die „Werte, die während des Renderns erzeugt werden“, ändern

Beim Arbeiten an der Stufe „But You Can Change“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgszeichen sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreiber ohne das Durchlesen des gesamten Systems überprüfen können. Betrachten Sie Effekte als Synchronisierung mit der Außenwelt – nicht als Ersatz für berechnete Werte während der Darstellung.

function ProductList({ products }: { products: Product[] }) {
  // ✅ this array was just created in this render — handle it however you like
  const sorted = [...products].sort((a, b) => a.price - b.price);
  return (
    <ul>
      {sorted.map((p) => (
        <li key={p.id}>{p.name}</li>
      ))}
    </ul>
  );
}

Mystery 1 gelöst – Warum StrictMode Dinge zweimal ausführt

Beim Bearbeiten der Phase „Mystery 1 Solved Why“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgszeichen sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Wiederherstellungsprozess gemeinsam. Wiederholversuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Betrachten Sie Nebeneffekte als Synchronisierung mit der Außenwelt – nicht als Ersatz für berechnete Werte während der Darstellung. Beim Bearbeiten der Phase „Mystery 1 Solved Why“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgszeichen sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Ergebnisse, definieren Sie Erfolgsprüfungen und lehnen Sie stille, teilweise abgeschlossene Abläufe ab.

// main.tsx — in development, the components inside this render twice
createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>,
);

Wohin also gehören Nebeneffekte?

Die Side-Stage-Methode funktioniert am besten, wenn sie als messbare Ebene betrachtet wird. Erfassen Sie einen erfolgreichen Fall, einen Fehlerfall sowie die Notizen zum Rollback, bevor Sie den Umfang erweitern. Erfassen Sie außerdem die Laufzeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn sich der Prozess von einer Demo in gemeinsam genutzte Umgebungen verschiebt. Halten Sie die Render-Arbeiten kostengünstig und verschieben Sie aufwändige Berechnungen erst nach Messung hinter die Memoisierung – eine vorzeitige Memoisierung kann fehlerhafte Eigenschaften verbergen.

// 🔴 side effect during rendering — fires on every render
function ProductPage({ id }: { id: number }) {
  logView(id); // a side effect in the render body — not allowed
  return <h1>Product {id}</h1>;
}

// ✅ in an event handler — runs only at the moment the user clicks
function BuyButton({ id }: { id: number }) {
  return <button onClick={() => logPurchase(id)}>Buy</button>;
}

Rätsel 2 gelöst – Warum der React-Compiler auf Reinheit setzt

The Mystery 2 Solved: Warum die Stage am besten als messbare Oberfläche behandelt wird. Erfassen Sie einen erfolgreichen Fall, einen Fehlerfall sowie die Rollback-Anmerkung, bevor Sie den Umfang erweitern. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreuer ohne das Durchlesen des gesamten Graphen überprüfen können. Halten Sie die Render-Arbeit kostengünstig und verschieben Sie aufwändige Berechnungen erst nach Messung hinter die Memoisierung – eine vorzeitige Memoisierung kann Fehler mit veralteten Eigenschaften verbergen.

// 🔴 not pure → the compiler skips optimization (ESLint points at this component)
let renderCount = 0;
function RenderCounter() {
  renderCount++; // mutating an external variable during render — a violation
  return <p>{renderCount}</p>;
}

// ✅ pure → the compiler memoizes automatically (reuse the previous result when inputs match)
function Label({ text }: { text: string }) {
  return <p>{text}</p>;
}

function App() {
  return (
    <>
      <RenderCounter />
      <Label text="Pure Component" />
    </>
  );
}

export default App;

Die UI als Baum betrachten

The Seeing UI als Bühne funktioniert am besten, wenn sie als messbare Oberfläche betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Dokumentieren Sie gleichzeitig den erfolgreichen Ablauf sowie den Wiederherstellungsprozess. Wiederholversuche, menschliche Kontrollen und die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Halten Sie die Renderarbeiten kostengünstig und verschieben Sie aufwändige Berechnungen erst nach Messung hinter die Memoisierung – eine vorzeitige Memoisierung kann fehlerhafte Eigenschaften verbergen. The Seeing UI als Bühne funktioniert am besten, wenn sie als messbare Oberfläche betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Betrachten Sie diese Stufe als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Ergebnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab.

function App() {
  return <ProductList products={products} />;
}

function ProductList({ products }: { products: Product[] }) {
  return (
    <ul>
      {products.map((p) => (
        <ProductCard key={p.id} product={p} />
      ))}
    </ul>
  );
}
App
└─ ProductList
   ├─ ProductCard
   ├─ ProductCard
   └─ ProductCard

Zusammenfassung

Zur Abschlussphase sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden, bevor der Code geändert wird. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten sowie Kosten für Token oder Abfragen sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Weg von einer Demo-Umgebung in gemeinsam genutzte Umgebungen wechselt. Der Zustand sollte zusammen mit dem Komponenten gespeichert werden, der für die Änderung verantwortlich ist. Das Hinzufügen aller Daten in einen globalen Speicher erschwert es, Timing-Probleme zu erkennen.

Referenzen

In der Phase der Referenzen sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden, bevor der Code geändert wird. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Die Konfiguration sollte außerhalb des Anwendungscode gespeichert werden. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den die Operator überprüfen können, ohne den gesamten Codeverlauf durchlesen zu müssen. Der Zustand sollte zusammen mit dem Komponenten gespeichert werden, der für die Mutation verantwortlich ist. Das Zusammenfassen aller Daten in einem globalen Speicher erschwert es, Zeitprobleme zu erkennen.

Operative Checkliste

Während der Bearbeitung der operativen Checkliste sollte zunächst der Vertrag festgehalten werden: erforderliche Eingaben, Signal für Erfolg sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben.

Man sollte kleine, testbare Einheiten vor umfangreichen Skripten bevorzugen. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren.

Betrachten Sie Effekte als Synchronisierung mit der Außenwelt, nicht als Ersatz für berechnete Werte während der Renderung.

Festlegen Sie die Versionen der Abhängigkeiten und speichern Sie den Bild-Digest, mit dem die Demo ausgeführt wurde. Reproduzierbarkeit ist besser als „stammesweises Wissen“.

Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab.

Betrachten Sie Effekte als Synchronisierung mit der Außenwelt, nicht als Ersatz für berechnete Werte während der Renderung.

Vor der Einführung des Stacks sollten Versionen eingefroren werden, ein „goldener“ Transkript für den kritischen Pfad erstellt und die Rollback-Schritte bestätigt werden. Gemeinsam genutzte Umgebungen benötigen Rate Limits, Überprüfungen der Nutzerzuordnung sowie einen klaren Verantwortlichen für die Rotation von Geheimnissen. Man sollte langweilige Zuverlässigkeit vor cleveren, einmaligen Demonstrationen bevorzugen.

Batch-Hinweis für d707b555add8: Halten Sie die Provider-Schlüssel außerhalb des Repositories, legen Sie eine Obergrenze für Tokens pro Sitzung fest und speichern Sie die Transkripte neben den Eval-Fixtures, damit spätere Modellwechsel vergleichbar bleiben.