Skip to content
Created: September 23, 2025

How does a setState go around in a big circle and accurately "return" to the corresponding Fiber?

setState → dispatchAction → lane → Fiber This chain is completely disassembled.

Overview (memorize the entire link first) ​

txt
setState
 → dispatchSetState
 → requestUpdateLane
 → enqueueUpdate (hook.queue)
 → scheduleUpdateOnFiber
 → markRootUpdated
 → renderRoot
 → beginWork(fiber)
  • 👉 Key point: Fiber has been "captured" during setState

1. The "magic" of setState: it binds Fiber from the beginning ​

You first recall the setState returned by useState:

ts
const [state, setState] = useState(0)

The truth is: 👇 ​

ts
const dispatch = dispatchSetState.bind(
  null,
  currentlyRenderingFiber,
  hook.queue
)
  • 👉 setState is a closure
  • 👉 It has already been remembered:
  • fiber
  • updateQueue

⚠️ Key conclusions:

setState does not need to "check Fiber" because it comes with Fiber from the beginning

2. dispatchSetState: the real entrance to update ​

ts
function dispatchSetState(fiber, queue, action) {
  const lane = requestUpdateLane(fiber)

  const update = {
    lane,
    action,
    next: null,
  }

  enqueueUpdate(queue, update)
  scheduleUpdateOnFiber(fiber, lane)
}

Three key things happen in this step:

  • 1️⃣ Determine priority (lane)
  • 2️⃣ Put update into hook.queue
  • 3️⃣ Notify the scheduling system: This Fiber needs to be updated

3. What is lane?(upgrade to Vue scheduler) ​

Vue: ​

txt
trigger → jobQueue

React: ​

txt
update → lane → root.pendingLanes
lane essence ​

lane = priority lane expressed in bits

ts
SyncLane        = 0b0001
InputLane       = 0b0010
TransitionLane  = 0b0100
IdleLane        = 0b1000
  • 👉 Multiple lanes can exist at the same time
  • 👉 Scheduler selects the highest priority each time

What does requestUpdateLane do? ​

ts
function requestUpdateLane(fiber) {
  if (isSync) return SyncLane
  if (isTransition) return TransitionLane
  return DefaultLane
}
  • Click → Sync
  • startTransition → Transition
  • Normal setState → Default

4. enqueueUpdate: Where does the update "hang"? ​

for Hooks(useState) ​

ts
queue.pending = update

Update structure:

txt
Fiber
 └─ memoizedState
     └─ hook
         └─ queue
             └─ pending → update
  • 👉 update is not in Fiber itself
  • 👉 on hook.queue

5. scheduleUpdateOnFiber: truly “return to Fiber” ​

ts
function scheduleUpdateOnFiber(fiber, lane) {
  const root = markUpdateLaneFromFiberToRoot(fiber, lane)
  ensureRootIsScheduled(root)
}

markUpdateLaneFromFiberToRoot ​

txt
fiber
  ↑ return
parent
  ↑ return
...
root

Follow fiber.return all the way up:

ts
parent.lanes |= lane
root.pendingLanes |= lane
  • 👉 In this step, Fiber successfully "notified" the entire tree

6. Why must we “return to root”? ​

Because:

  • Scheduling is root level
  • render starts from root
  • Scheduler does not care about a fiber
txt
root.pendingLanes != 0
 → root 需要 render

7. When does Scheduler actually render? ​

ts
performConcurrentWorkOnRoot(root)
  • 1️⃣ Select the highest priority lane

  • 2️⃣ renderRoot(lane)

  • 3️⃣ workLoop

  • 4️⃣ beginWork(root.child)

  • 👉 Finally back to the original Fiber

8. Render stage: update is consumed ​

When render to the corresponding Fiber:

ts
updateFunctionComponent
 → renderWithHooks
 → updateState
ts
const pending = hook.queue.pending
  • consumption update
  • Calculate new state
  • Write hook.memoizedState
  • 👉 Closed loop completed

9. Why does React update "come in a big circle"? ​

You may feel:

"How direct is the Vue trigger effect?"

The reason is:

React must support: ​

  • Concurrency
  • interrupt
  • priority
  • discard render
  • 👉 So update must be a "delayed consumption description" instead of immediate execution

10. Vue effect vs React update (Contrast) ​

VueReact
setter triggerdispatchAction
dep positioningclosure remember Fiber
schedulerlane
effect executionrender rerun
Accurate updatesInterruptible updates

11. Summary ​

setState can "return to Fiber" not because React is smart, It's because setState has "remembered which fiber it came from" from the moment it was born.