⚛️ React Fiber: Advanced Guide
Introduction: Why Fiber?
React Fiber is a complete rewrite of the React core algorithm (introduced in React 16) to solve performance and concurrency limitations. Fiber enables:
- ⏱️ Incremental rendering (time-slicing)
- 🛑 Pausing, resuming, and discarding work mid-render
- ⭐ Prioritizing updates
- 🌳 Better handling of large component trees
Fiber represents a unit of work — a lightweight object describing a component, its props, state, and tree relations.
The Fiber Data Structure
A Fiber is a JS object with key properties:
interface Fiber { tag: number; key: string | null; elementType: any; type: any; stateNode: any; return: Fiber | null; child: Fiber | null; sibling: Fiber | null; index: number; ref: any; pendingProps: any; memoizedProps: any; memoizedState: any; updateQueue: UpdateQueue | null; effectTag: number; nextEffect: Fiber | null; alternate: Fiber | null; }
Detailed Property Explanations
tag
: Fiber type (FunctionComponent, HostComponent, etc.)key
: used during reconciliationelementType
vstype
: JSX type vs resolved component typestateNode
: instance or DOM nodereturn/child/sibling
: tree structureindex
: sibling positionref
: React refspendingProps
: upcoming render propsmemoizedProps
/memoizedState
: last committed props/stateupdateQueue
: pending updates stored in Current FibereffectTag
: DOM operationsnextEffect
: linked list for commitalternate
: links Current ↔ WIPCurrent vs WIP:
current
= last committed tree,workInProgress
= in-progress treeHooks stored as linked list (
memoizedState
) on function component fibers
Rendering Pipeline
Render Phase (Reconciliation)
- Pure phase, no DOM mutations
- Builds WIP Fiber tree, cloned from Current if exists
- Depth-first traversal
- Applies updates from each Fiber’s update queue
- Marks fibers with effect tags
- Supports pausing, resuming, discarding WIP
Commit Phase Overview
- Runs after WIP tree built
- Synchronous phase: DOM mutations
- Sub-phases: Before Mutation, Mutation, Layout Effects, Passive Effects
Commit Phase in Detail 🏁
1. Before Mutation Phase
-
getSnapshotBeforeUpdate
runs - DOM snapshot captured before mutations
- WIP in memory, Current Fiber unchanged
- Previous effect cleanups run
2. Mutation Phase
- Apply DOM changes (Placement, Update, Deletion)
- Depth-first traversal
- Batched DOM writes
- Ref attachments/detachments handled
3. Layout Effects Phase
-
componentDidMount
,componentDidUpdate
,useLayoutEffect
run - After DOM mutations, before browser paint
- Synchronous layout calculations
4. Passive Effects Phase
-
useEffect
hooks run asynchronously after paint - Non-blocking side effects
- Cleanup of previous effects handled
WIP → Current Swap
- After commit, WIP becomes Current
- Ensures consistent UI even if new render scheduled mid-commit
DOM Insertion & Updates
- Depth-first DOM insertion
- Deletes handled carefully
- Atomicity guaranteed
- Refs updated
Special Notes
- WIP can be discarded if higher-priority update arrives
- Only fully completed WIP trees committed
- UI never reflects half-done work
- Commit errors trigger error boundaries
Hooks & Fiber
- Hooks stored on Fiber (
memoizedState
) -
useState
/useReducer
applied during WIP render - On commit,
memoizedState
becomes part of Current - Scheduler clones Current → WIP; pending updates applied
- Deterministic state even if WIP discarded
Common Scenarios
Half-done WIP
- Paused WIP doesn’t affect DOM
- May resume or be discarded
- New WIP clones Current and reapplies updates if discarded
Update Queue
- Stored on Current Fiber
- Survives WIP discard
- Functional updates applied in order
Multiple setState
- Batched: single render
- Unbatched: separate WIP per update
- Object states merged shallowly
[state, setState]
recreation
- New array per render
- Prevents mutation of previous hooks
Fiber Interconnections
-
return
,child
,sibling
,alternate
- Current ↔ WIP swap keeps references
- Children cloned when WIP created
Diagrams / Pseudo-code
Fiber Tree Example
HostRootFiber └─ AppFiber ├─ HeaderFiber └─ ContentFiber ├─ Child1Fiber └─ Child2Fiber
- WIP tree created first render
- Commit swaps WIP → Current
- Hooks stored as linked list in function components
Update Queue Example
CounterFiber.updateQueue = { pending: { action: prev => prev + 1, next: null }, baseState: 0 }
- WIP render:
memoizedState = baseState + pending actions
setCount(c => c+1) -> enqueued in Current -> WIP applies -> memoizedState updated
Closing Notes
- Fiber enables incremental, interruptible, prioritized rendering
- WIP trees ephemeral; Current = source of truth
- Updates queued in Current, replayed in WIP
- Commit phase atomic
- Hooks integrated with Fiber
- Understanding Fiber internals helps optimize React and ace interviews
Author
Yogesh Bamanier
LinkedIn: https://www.linkedin.com/in/yogesh-007/
Top comments (4)
Some Important topics and features are covered in this post.
Note: Senior Level Post.
Really clear breakdown of React Fiber! Seeing how the WIP vs Current tree works helps demystify some of React’s more magical internals.
This post is a treasure trove for anyone looking to understand React Fiber! The way you’ve broken down complex concepts like the 'updateQueue' and commit phases is incredibly helpful. It’s posts like these that make the dev.to community such a great place for developers to learn and grow.
If you’re considering a follow-up, a visual walkthrough of the Fiber tree lifecycle (from creation to commit) could be a fantastic addition for readers who learn best through visuals. Just a suggestion!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.