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.
देखें कि React hooks को linked list के रूप में कैसे manage करता है।
Hooks को fiber नोड पर एक singly linked list के रूप में store किया जाता है। जब आपका component render होता है, React इस list को order में walk करता है — प्रत्येक hook call (useState, useEffect, useRef, आदि) को उसकी stored state से match करता है। इसीलिए Hooks के Rules exist हैं: यदि आप conditionally hooks call करते हैं, तो list order बदल जाता है और React गलत hook के लिए गलत state पढ़ता है।
प्रत्येक hook call (useState, useEffect, useRef, useMemo…) एक memoizedState field और एक next pointer के साथ एक 'Hook' object बनाता है। React प्रत्येक को call order में list में append करता है। List fiber नोड के memoizedState field पर store होती है।
एक useState hook object store करता है: memoizedState (current value), queue (pending setState calls की linked list), और dispatch (वह setState function जो आप component में उपयोग करते हैं)। Dispatch function stable है — यह renders के बीच कभी नहीं बदलता।
जब आप setState(newValue) call करते हैं, React state को immediately update नहीं करता। इसके बजाय, यह hook की queue में एक Update object append करता है और fiber का re-render schedule करता है। एक event handler में कई setState calls एक re-render में batch हो जाती हैं।
अगले render पर, React hooks list को फिर से walk करता है। प्रत्येक useState hook के लिए, यह सभी queued updates को order में process करता है (या useReducer के लिए reducer function call करता है)। अंतिम computed value नई memoizedState बन जाती है।
एक effect hook object store करता है: create (वह callback जो आपने pass किया), destroy (वह cleanup function जो उसने पिछली बार return की), deps (dependency array), और एक tag जो दर्शाता है कि यह useEffect है, useLayoutEffect है, या useInsertionEffect।
Hooks fiber नोड पर singly linked list के रूप में store होते हैं। Call order = list order। Conditional hooks list को तोड़ देते हैं।
Hook object पर वह field जो current value store करती है। useState के लिए: state value। useRef के लिए: '{' current: value '}'। useMemo के लिए: cached result।
प्रत्येक hook object पर pending setState calls की एक circular linked list जो अगले render पर process होने की प्रतीक्षा करती है। Multiple updates एक queue flush में batch होते हैं।
React render phase के आधार पर hook implementation swap करता है। पहले render के दौरान: HooksDispatcherOnMount। Re-renders के दौरान: HooksDispatcherOnUpdate। इसीलिए hooks को components के बाहर call नहीं किया जा सकता।
Hooks को केवल top level पर (conditionals/loops के अंदर नहीं) और केवल React functions से call करें। ये rules इसलिए exist करते हैं क्योंकि React hooks को linked list में उनकी position से identify करता है।
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
Hooks internals को समझना explain करता है कि Rules of Hooks arbitrary restrictions नहीं बल्कि technical necessities क्यों हैं। यह यह भी explain करता है कि useState setter function हमेशा stable क्यों है (यह value से नहीं बल्कि queue से attached है), renders के पार hooks क्यों काम करते हैं (वे fiber पर persist होते हैं), और आप custom hooks क्यों build कर सकते हैं — वे सिर्फ ऐसे functions हैं जो दूसरे hooks call करते हैं, list में और nodes add करते हैं।
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.