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.
JSX से पिक्सल तक की पूरी यात्रा — रेंडर ट्रिगर करें और हर चरण देखें।
हर बार जब React render करता है, यह एक predictable two-phase pipeline से गुज़रता है: Render Phase और Commit Phase। render phase pure और interruptible है — React आपके components call करता है और एक new fiber tree build करता है। commit phase synchronous और side-effectful है — React computed changes को real DOM पर apply करता है और effects fire करता है।
Build time पर, JSX जैसे <Button color='blue'>Click</Button> → React.createElement(Button, '{' color: 'blue' '}', 'Click') बन जाता है। यह एक plain object tree बनाता है — virtual DOM।
React fiber tree walk करते हुए प्रत्येक component function (या render() method) call करता है। यह phase pure है और कोई side effects नहीं बनाती — concurrent mode में React इसे किसी भी समय interrupt और restart कर सकता है।
React नए output की पिछली fiber tree से तुलना करता है। यह प्रत्येक fiber को एक effect tag से mark करता है: Update, Placement (insert), या Deletion। परिणाम एक 'effect list' है — pending work वाले fibers की flat list।
React class components पर getSnapshotBeforeUpdate() call करता है और passive effects schedule करता है। यह sub-phase किसी भी DOM mutations होने से पहले चलता है।
React effect list walk करता है और सभी DOM mutations synchronously apply करता है: insertions, updates, deletions। इसके बाद, DOM नया UI reflect करता है।
useLayoutEffect callbacks DOM mutation के बाद लेकिन browser paint से पहले synchronously चलते हैं। फिर browser paint करता है। अंत में, useEffect callbacks paint के बाद asynchronously चलते हैं।
Pure, side-effect-free phase जहाँ React components call करता है और नई fiber tree build करता है। Concurrent mode में interrupt हो सकती है।
Synchronous phase जहाँ React DOM mutations apply करता है और lifecycle methods/effects fire करता है। Interrupt नहीं हो सकती।
DOM mutation के बाद, browser paint से पहले synchronously fire होता है। DOM measurements के लिए उपयोग करें। Painting block करता है।
Browser paint के बाद asynchronously fire होता है। Painting block नहीं करता — subscriptions, fetches, और non-visual side effects के लिए आदर्श।
Development में, React side effects detect करने के लिए render phase में components को दो बार render करता है। केवल एक commit होता है।
1function MyComponent() {2 // Fires: after every render, after browser paint (async)3 useEffect(() => {4 console.log('3. useEffect — DOM painted, async');5 return () => console.log('cleanup');6 });78 // Fires: after every render, before browser paint (sync)9 useLayoutEffect(() => {10 console.log('2. useLayoutEffect — DOM mutated, not painted');11 });1213 console.log('1. Render phase — pure, no side effects');14 return <div />;15}16// Order: Render → DOM mutation → useLayoutEffect → Paint → useEffect
Pipeline को समझना आपको code को सही जगह रखने में मदद करता है। DOM measurements useLayoutEffect (paint से पहले) में होने चाहिए। Data fetching useEffect (paint के बाद, non-blocking) में जाना चाहिए। पहले render से पहले होने वाली initialization useState initializer या useMemo में जाती है। इसे गलत करने से visual flashes, layout jumps, या missed renders होते हैं।
You're building a tooltip that positions itself relative to a target element. Using useEffect, the tooltip first renders at (0,0), then jumps to the correct position — causing a visible flash.
useEffect fires AFTER the browser paints. So the sequence is: Render (tooltip at 0,0) → Paint (user sees misplaced tooltip) → useEffect (measure & reposition) → Re-render → Paint (correct). The first paint shows the wrong position.
Switch to useLayoutEffect which fires AFTER DOM mutation but BEFORE paint. The sequence becomes: Render → DOM mutation → useLayoutEffect (measure & update) → Paint (correct position). The user never sees the wrong position because the browser hasn't painted yet.
Takeaway: Use useLayoutEffect for any DOM measurement or mutation that affects visual layout (tooltips, popovers, scroll position, animations). Use useEffect for everything else (data fetching, analytics, subscriptions).
You add console.log statements to debug when state changes propagate. The logs appear in an unexpected order: render logs appear before effect logs, and cleanup logs appear between them.
Without understanding the pipeline phases, developers assume effects run 'during' rendering. They place side effects in the render function body (causing bugs) or misread the log order and chase phantom timing issues.
The rendering pipeline has strict phases: Render (pure, produces VDOM) → Commit (DOM writes) → Layout Effects (sync, before paint) → Paint (browser) → Effects (async, after paint). Each console.log appears in pipeline order. Understanding this order lets you read debug output correctly and place code in the right phase.
Takeaway: The rendering pipeline is NOT a single step — it's 5 distinct phases with different timing guarantees. Most React bugs come from putting code in the wrong phase (e.g., side effects in render, DOM reads in useEffect instead of useLayoutEffect).