Inside React’s useEffect: A Deep Dive into the Fiber Source Code

This article dissects the inner workings of React's useEffect hook by tracing its implementation through the React Fiber architecture, from mountEffect and updateEffect functions to the commit phase, revealing how side‑effects are scheduled, created, and cleaned up in modern React applications.

QQ Music Frontend Team
QQ Music Frontend Team
QQ Music Frontend Team
Inside React’s useEffect: A Deep Dive into the Fiber Source Code

Overview of useEffect in React

The article explains why useEffect was introduced, how it replaces lifecycle methods in class components, and how it separates side‑effects from rendering logic.

Mount and Update Implementations

Both mountEffect and updateEffect are defined in ReactFiberHooks.js. They create a new hook, compute nextDeps, set the sideEffectTag, and store an Effect object via pushEffect. When dependencies have not changed, updateEffect uses NoHookEffect to skip execution.

pushEffect Function

pushEffect(tag, create, destroy, deps)

builds an Effect node (a circular linked list) and adds it to the component's updateQueue. The queue is a simple object with a lastEffect pointer, forming a circular list of effects for the component.

Component Update Queue

The componentUpdateQueue holds the effect list. When the first effect is added, the queue is initialized and its lastEffect points to the new effect; subsequent effects are linked in a circular fashion.

Render Flow from ReactDOM to Fiber

Rendering starts with ReactDOM.render, which calls updateContainer in ReactFiberReconciler.js. This function creates a root update and schedules work via scheduleWork. The scheduler eventually invokes renderRoot, which runs the workLoop (or workLoopSync) to process units of work.

performUnitOfWork and beginWork

performUnitOfWork

repeatedly calls beginWork for each fiber. For function components, beginWork executes renderWithHooks, which runs the component function, registers hooks, and builds the effect list.

Commit Phase

When the render phase finishes, commitRoot is called. It extracts the effect list from the finished work, then runs three phases:

commitBeforeMutationEffects
commitMutationEffects
commitLayoutEffects

Each phase iterates over the same circular effect list.

commitHookEffectList

The core of useEffect handling resides in commitHookEffectList(unmountTag, mountTag, finishedWork). It retrieves the component's updateQueue, walks the circular list of Effect objects, and for each effect:

If the tag matches unmountTag, it calls the stored destroy function.

If the tag matches mountTag, it calls the stored create function and saves its return value as the new destroy function.

Effects with the NoHookEffect tag are ignored, which explains why some hooks do nothing in certain phases.

Key Takeaways

The article demonstrates how React transforms a declarative useEffect call into a low‑level effect list, schedules it through the Fiber work loop, and finally executes or cleans up side‑effects during the commit phases. Understanding this pipeline clarifies the behavior of dependency arrays, cleanup functions, and the timing of effect execution.

For a visual overview of the Fiber render and commit phases, see the diagram from the React Conf 2017 talk "A Cartoon Intro to Fiber".
Fiber render and commit phases
Fiber render and commit phases
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptReactFiberuseEffect
QQ Music Frontend Team
Written by

QQ Music Frontend Team

QQ Music Web Frontend Team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.