Der FehlerReact Hook „useState“ wird bedingt aufgerufen. React Hooks müssen in jedem Komponenten-Renderin genau derselben Reihenfolge aufgerufen werden ist einer der häufigsten React-Fehler. Es verstößt gegen die Hook-Regeln. Hier erfahren Sie, warum es passiert und wie Sie jede Variante beheben können.
📋 Table of Contents
- Warum diese Regel existiert
- Der gebrochene Code
- Fix 1: Hooks zuerst aufrufen, Condition später
- Fix 2: Hook innerhalb eines Bedingungsblocks
- Fix 3: Einhaken in einer Schleife
- Fix 4: Hook nach einer vorzeitigen Rückkehr
- Die zwei Regeln der Hooks
- Bedingte Logik richtig handhaben
- Erzwingen Sie die Regeln mit ESLint
- Häufig gestellte Fragen
- Fazit
Warum diese Regel existiert
Reagieren Sie auf Tracks-Hooks mit ihremAufrufreihenfolge, nicht namentlich. Bei jedem Rendern erwartet React dieselben Hooks in derselben Reihenfolge. Wenn sich ein Hook innerhalb einer Bedingung befindet, wird er möglicherweise bei einem Rendervorgang ausgeführt, beim nächsten jedoch nicht. Dadurch wird das interne Tracking von React unterbrochen und der Status wird dem falschen Hook zugewiesen.
Der gebrochene Code
// 🐛 Hook inside a condition — VIOLATES rules of hooks
function Profile({ userId }) {
if (!userId) {
return <div>No user</div>; // early return BEFORE hooks
}
const [user, setUser] = useState(null); // ❌ conditionally called
// If userId is falsy, this hook is skipped — breaks React's tracking
return <div>{user?.name}</div>;
}
Fix 1: Hooks zuerst aufrufen, Condition später
// ✅ All hooks at the top, unconditionally
function Profile({ userId }) {
const [user, setUser] = useState(null); // always called
// Conditional logic AFTER all hooks
if (!userId) {
return <div>No user</div>;
}
return <div>{user?.name}</div>;
}
Fix 2: Hook innerhalb eines Bedingungsblocks
// 🐛 useEffect inside an if
function Component({ isActive }) {
if (isActive) {
useEffect(() => { // ❌ conditional hook
console.log('active');
}, []);
}
}
// ✅ Move the condition INSIDE the hook
function Component({ isActive }) {
useEffect(() => {
if (isActive) { // condition inside the hook
console.log('active');
}
}, [isActive]);
}
Fix 3: Einhaken in einer Schleife
// 🐛 Hook in a loop — order changes if items.length changes
function List({ items }) {
return items.map(item => {
const [selected, setSelected] = useState(false); // ❌ in a loop
return <Item key={item.id} />;
});
}
// ✅ Extract into a child component — each has its own hooks
function List({ items }) {
return items.map(item => <Item key={item.id} item={item} />);
}
function Item({ item }) {
const [selected, setSelected] = useState(false); // ✅ top level of component
return <div onClick={() => setSelected(!selected)}>{item.name}</div>;
}
Fix 4: Hook nach einer vorzeitigen Rückkehr
// 🐛 Hook after a conditional return
function Widget({ data }) {
const [count, setCount] = useState(0);
if (!data) return null; // early return
const [name, setName] = useState(''); // ❌ never reached when !data
return <div>{name}: {count}</div>;
}
// ✅ ALL hooks before ANY conditional return
function Widget({ data }) {
const [count, setCount] = useState(0);
const [name, setName] = useState(''); // moved up
if (!data) return null; // early return AFTER all hooks
return <div>{name}: {count}</div>;
}
Die zwei Regeln der Hooks
- Rufen Sie nur Hooks auf der obersten Ebeneauf – niemals innerhalb von Bedingungen, Schleifen oder verschachtelten Funktionen. Immer in der gleichen Reihenfolge.
- Rufen Sie Hooks nur von React-Funktionen auf – Reagieren Sie auf Komponenten oder benutzerdefinierte Hooks (Funktionen, die mit
usebeginnen). Nicht von regulären JavaScript-Funktionen.
Bedingte Logik richtig handhaben
function Dashboard({ user, showStats }) {
// ✅ Always call all hooks unconditionally
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Conditions go INSIDE the hook, not around it
if (showStats) {
fetchStats().then(setData).finally(() => setLoading(false));
} else {
setLoading(false);
}
}, [showStats]);
// Conditional RENDERING is fine — it's not a conditional hook
if (!user) return <Login />;
if (loading) return <Spinner />;
return showStats ? <Stats data={data} /> : <Overview />;
}
Erzwingen Sie die Regeln mit ESLint
npm install --save-dev eslint-plugin-react-hooks
// .eslintrc — catches these errors before runtime
{
"plugins": ["react-hooks"],
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
}
}
Häufig gestellte Fragen
F: Warum können Hooks nicht bedingt sein? Es scheint willkürlich.
A: React identifiziert Hooks anhand ihrer Aufrufreihenfolge (erster useState, zweiter useState usw.), nicht anhand ihres Namens. Wenn ein Hook manchmal übersprungen wird, verschiebt sich die Reihenfolge und React weist den Status dem falschen Hook zu. Eine konsistente Reihenfolge sorgt dafür, dass Hooks funktionieren.
F: Kann ich Bedingungen innerhalb eines Hooks verwenden?
A: Ja! Bedingungen INNERHALB eines Hooks (zum Beispiel innerhalb des useEffect-Callbacks) sind in Ordnung. Die Regel verbietet nur das bedingte AUFRUFEN des Hooks selbst.
F: Wie führe ich einen Effekt bedingt aus?
A: Fügen Sie die Bedingung in den Effektkörper ein und fügen Sie die Bedingungsvariable in das Abhängigkeitsarray ein:useEffect(() => { if (cond) {...} }, [cond]).
F: Was ist mit bedingtem Rendering – ist das erlaubt?
A: Ja. Das bedingte Rendern (das Zurückgeben unterschiedlicher JSX basierend auf dem Status) ist völlig in Ordnung, solange alle Hooks vor einer bedingten Rückgabe aufgerufen werden. Rendering-Bedingungen sind keine Hook-Bedingungen.
F: Kann ich einen benutzerdefinierten Hook bedingt aufrufen?
A: Nein – benutzerdefinierte Hooks folgen denselben Regeln, da sie Hooks intern aufrufen. Rufen Sie sie bedingungslos auf der obersten Ebene auf und fügen Sie Bedingungen in sie ein.
Fazit
Der Fehler „React Hook wird bedingt aufgerufen“ bedeutet, dass sich ein Hook in einer Bedingung, Schleife oder nach einer vorzeitigen Rückkehr befindet. Der Fix ist immer derselbe:Rufen Sie ALLE Hooks bedingungslos am Anfang Ihrer Komponente auf, bevor bedingte Rückgaben oder Logikerfolgen . Platzieren Sie Bedingungen INNERHALB der Haken (im Effektkörper), nicht um sie herum. Installieren Sieeslint-plugin-react-hooks diese Fehler automatisch abzufangen, bevor sie zur Laufzeit gelangen – das ist der beste Schutz vor Verstößen gegen Hook-Regeln.
🔗 Share this article
✍️ Leave a Comment