Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Sehen Sie, wie React Hooks als verkettete Liste verwaltet, Statusaktualisierungen verarbeitet und neu rendert.
Hooks werden als einfach verkettete Liste auf dem Fiber-Knoten gespeichert. Wenn Ihre Komponente rendert, durchläuft React diese Liste in Reihenfolge — und ordnet jeden Hook-Aufruf (useState, useEffect, useRef usw.) dem gespeicherten Zustand zu. Deshalb existieren die Rules of Hooks: Wenn Sie Hooks bedingt aufrufen, ändert sich die Listenreihenfolge und React liest den falschen Zustand für den falschen Hook.
Jeder Hook-Aufruf (useState, useEffect, useRef, useMemo…) erstellt ein 'Hook'-Objekt mit einem memoizedState-Feld und einem next-Zeiger. React hängt jeden in Aufruffolge an die Liste an. Die Liste wird im memoizedState-Feld des Fiber-Knotens gespeichert.
Ein useState-Hook-Objekt speichert: memoizedState (aktueller Wert), queue (verkettete Liste ausstehender setState-Aufrufe) und dispatch (die setState-Funktion, die Sie in Ihrer Komponente verwenden). Die dispatch-Funktion ist stabil — sie ändert sich nie zwischen Renderings.
Wenn Sie setState(neuerWert) aufrufen, aktualisiert React den Zustand nicht sofort. Stattdessen hängt es ein Update-Objekt an die Queue des Hooks an und plant ein Re-Rendering des Fibers. Mehrere setState-Aufrufe in einem Event-Handler werden zu einem einzigen Re-Rendering zusammengefasst.
Beim nächsten Rendering durchläuft React die Hooks-Liste erneut. Für jeden useState-Hook verarbeitet es alle in der Warteschlange stehenden Updates, indem es sie der Reihe nach ausführt (oder die Reducer-Funktion für useReducer aufruft). Der endgültig berechnete Wert wird zum neuen memoizedState.
Ein Effect-Hook-Objekt speichert: create (den übergebenen Callback), destroy (die zuletzt zurückgegebene Bereinigungsfunktion), deps (das Dependency-Array) und einen Tag, der angibt, ob es sich um useEffect, useLayoutEffect oder useInsertionEffect handelt.
Hooks werden als einfach verkettete Liste auf dem Fiber-Knoten gespeichert. Aufruffolge = Listenfolge. Bedingte Hooks brechen die Liste.
Das Feld auf einem Hook-Objekt, das dessen aktuellen Wert speichert. Bei useState: der Zustandswert. Bei useRef: '{' current: Wert '}'. Bei useMemo: das gecachte Ergebnis.
Eine zirkuläre verkettete Liste von setState-Aufrufen, die beim nächsten Rendering verarbeitet werden. Mehrere Updates werden in einem Queue-Flush gebündelt.
React tauscht die Hook-Implementierung je nach Render-Phase aus. Beim ersten Rendering: HooksDispatcherOnMount. Bei Re-Renderings: HooksDispatcherOnUpdate. Deshalb können Hooks nicht außerhalb von Komponenten aufgerufen werden.
Hooks nur auf oberster Ebene aufrufen (nie in Bedingungen/Schleifen) und nur aus React-Funktionen. Diese Regeln existieren, weil React Hooks nach ihrer Position in der verketteten Liste identifiziert.
1// Your component:2function Counter() {3 const [count, setCount] = useState(0); // Hook 14 const [name, setName] = useState('Bob'); // Hook 25 const ref = useRef(null); // Hook 367 useEffect(() => { ... }, [count]); // Hook 48}910// React's internal hooks linked list for this fiber:11Hook1 { memoizedState: 0, next: Hook2 } // count12Hook2 { memoizedState: 'Bob', next: Hook3 } // name13Hook3 { memoizedState: { current: null }, next: Hook4 } // ref14Hook4 { memoizedState: { create, destroy, deps: [0] }, next: null }1516// If you conditionally call hook 2:17// Hook1 → Hook3 → Hook4 (Hook2 slot is now useRef!)18// React reads "Bob" as the ref's current value → BUG
Das Verstehen der Hooks-Interna erklärt, warum die Rules of Hooks keine willkürlichen Einschränkungen sind, sondern technische Notwendigkeiten. Es erklärt auch, warum die useState-Setter-Funktion immer stabil ist (sie ist an die Queue gebunden, nicht an den Wert), warum Hooks über Renderings hinweg funktionieren (sie sind auf dem Fiber gespeichert) und warum man eigene Hooks erstellen kann — sie sind nur Funktionen, die andere Hooks aufrufen und weitere Knoten zur Liste hinzufügen.
You add an early return in a component for a loading state: `if (loading) return <Spinner />`. After the data loads, React crashes with 'Rendered more hooks than during the previous render.'
The early return is ABOVE some hook calls. On the first render (loading=true), React processes 2 hooks. On the second render (loading=false), it processes 5 hooks. React's linked list has 2 slots but encounters 5 hook calls — the list is corrupted.
Move ALL hook calls above any conditional returns. The early return must come AFTER the last hook call. React hooks are a linked list indexed by call order — the call count must be identical across every render of the same component.
Takeaway: The 'Rules of Hooks' aren't arbitrary restrictions — they're a direct consequence of the linked list data structure. React identifies hooks by position (call order), not by name. Changing the number of hooks between renders corrupts the list.
You build a custom `useToggle` hook used in 3 different components. You notice that toggling in one component doesn't affect the others — but you're confused about WHY, since they share the same hook code.
Developers sometimes assume custom hooks share state like a global singleton. They expect `useToggle()` in Component A and Component B to share the same boolean value, leading to incorrect architecture decisions.
Each component has its own fiber node with its own hooks linked list. When Component A calls `useToggle()`, React creates a hook node in Component A's list. Component B gets a completely separate hook node in its own list. Custom hooks are just a code-sharing mechanism — state is always local to the calling component's fiber.
Takeaway: Custom hooks share LOGIC, not STATE. Each component instance gets its own copy of the hook's state because each fiber maintains its own hooks linked list. To share state between components, you need Context, a state manager, or lifting state up.