facebook/reactMITd083ec1Report / request removal

Commit Phase

The commit phase turns a completed Fiber tree into observable host changes and lifecycle work. It runs the reconciler’s ordered commit passes over the finished tree, including host mutations, layout work, and passive effects.

It exists to make the transition from the previous tree to the next tree coherent. In particular, layout effects must see the already-mutated host tree, while cleanup must happen before new layout effects can interfere with sibling effects.

Sources: packages/react-reconciler/src/ReactFiberWorkLoop.js:3848-3850, packages/react-reconciler/src/ReactFiberWorkLoop.js:4118-4125

Core concepts

Commit boundary

A commit is the ordered processing of a finished Fiber tree after rendering has produced work. The work loop performs separate passes so mutation effects complete before layout effects.

Sources: packages/react-reconciler/src/ReactFiberWorkLoop.js:3848-3850

Before-mutation pass

The before-mutation pass prepares the host environment and examines effects that must run before host changes. commitBeforeMutationEffects calls prepareForCommit and then traverses the tree with commitBeforeMutationEffects_begin.

Sources: packages/react-reconciler/src/ReactFiberCommitWork.js:351-370

Mutation pass

The mutation pass applies changes represented by the finished tree. commitMutationEffects establishes commit state, resets effect timers, and delegates traversal to commitMutationEffectsOnFiber.

Sources: packages/react-reconciler/src/ReactFiberCommitWork.js:2016-2033

Layout effects

Layout effects are callbacks that run after the host tree has been mutated but before the commit’s layout work finishes. Function components use commitHookLayoutEffects; class components use commitClassLayoutLifecycles, callbacks, and ref attachment.

Sources: packages/react-reconciler/src/ReactFiberCommitWork.js:599-931

Passive effects

Passive effects are processed by a separate traversal. commitPassiveMountEffects delegates to commitPassiveMountOnFiber, where function components can run commitHookPassiveMountEffects. The passive phase may run synchronously during commit or asynchronously after paint, so it is distinct from the ordered mutation-to-layout sequence.

Sources: packages/react-reconciler/src/ReactFiberCommitWork.js:3745-3761, packages/react-reconciler/src/ReactFiberCommitWork.js:3822-4434, packages/react-reconciler/src/ReactFiberWorkLoop.js:4407-4415

How the commit is ordered

The synchronous commit has three primary sub-phases: before mutation, mutation, and layout. The source describes these as separate passes, with mutation effects before layout effects; passive effects are handled by the later passive traversal.

Sub-phaseMain entry pointMain responsibility
Before mutationcommitBeforeMutationEffectsPrepare the host environment and inspect pre-mutation work
MutationcommitMutationEffectsApply Fiber-driven host mutations and commit-time tree changes
LayoutcommitLayoutEffectsRun layout effects, class lifecycles, callbacks, host mounts, and refs
PassivecommitPassiveMountEffectsRun passive effect mounts after the primary commit ordering

This sequence is deliberately non-interleaved: the implementation performs all mutation effects before layout effects. That matters because layout work is explicitly described as reading the host tree after it has been mutated. A yield between related commit operations could expose a partially updated host tree to code that expects the commit boundary to be complete; this is an inference from the required ordering and the fact that layout effects read the mutated tree.

Commit pass order — Which commit pass runs next?

Evidence

The diagram shows each public pass delegating to its fiber-level traversal; the ordering between the primary passes is the mutation-before-layout rule described by the work loop.

Sources: packages/react-reconciler/src/ReactFiberWorkLoop.js:3848-3850, packages/react-reconciler/src/ReactFiberCommitWork.js:351-370, packages/react-reconciler/src/ReactFiberCommitWork.js:2016-2033, packages/react-reconciler/src/ReactFiberCommitWork.js:3050-3065, packages/react-reconciler/src/ReactFiberCommitWork.js:3745-3761, packages/react-reconciler/src/ReactFiberWorkLoop.js:4118-4125

What runs in each sub-phase

Before mutation

commitBeforeMutationEffects calls prepareForCommit using the root container, initializes the traversal cursor, and starts commitBeforeMutationEffects_begin. The traversal can process deletion-related before-mutation work and view-transition tracking before continuing through the finished tree.

Class components can also capture a snapshot before the host tree changes. commitClassSnapshot calls callGetSnapshotBeforeUpdates with the previous props and state, then stores the result on instance.__reactInternalSnapshotBeforeUpdate.

Sources: packages/react-reconciler/src/ReactFiberCommitWork.js:351-370, packages/react-reconciler/src/ReactFiberCommitWork.js:372-462, packages/react-reconciler/src/ReactFiberCommitEffects.js:634-706

Mutation

commitMutationEffects stores the active root and lanes, resets component effect timers, and invokes commitMutationEffectsOnFiber. The mutation work includes visibility changes: hideOrUnhideAllChildren walks child Fibers and delegates to hideOrUnhideAllChildrenOnFiber, which updates host instances, host text, or dehydrated Suspense boundaries.

Deletion also belongs to commit-time mutation handling. commitDeletionEffectsOnFiber detaches refs, traverses deletion effects, and removes or releases host-related resources according to the Fiber tag and renderer capabilities.

Layout-effect cleanup is intentionally performed during the mutation phase. commitHookLayoutUnmountEffects states that all layout destroy functions run before any create functions, preventing one component’s destroy function from interfering with another component’s ref or layout effect.

Sources: packages/react-reconciler/src/ReactFiberCommitWork.js:2016-2033, packages/react-reconciler/src/ReactFiberCommitWork.js:1199-1211, packages/react-reconciler/src/ReactFiberCommitWork.js:1213-1260, packages/react-reconciler/src/ReactFiberCommitWork.js:1487-1844, packages/react-reconciler/src/ReactFiberCommitEffects.js:113-138

Layout

commitLayoutEffects resets effect timers and invokes commitLayoutEffectOnFiber. For function-like components, layout hooks run when the Fiber has an update flag through commitHookLayoutEffects(finishedWork, HookLayout | HookHasEffect).

For class components, the layout traversal runs commitClassLayoutLifecycles, class callbacks, and ref attachment when their corresponding flags are present. A newly mounted class instance can therefore run componentDidMount in this phase. Host components can also run mount work such as commitHostMount, and refs are attached through safelyAttachRef.

Therefore, layout effects fire after DOM or other host mutations, not before them. The work loop names layout as the phase that reads the host tree after mutation, then calls commitLayoutEffects.

Sources: packages/react-reconciler/src/ReactFiberCommitWork.js:3050-3065, packages/react-reconciler/src/ReactFiberCommitWork.js:599-931, packages/react-reconciler/src/ReactFiberCommitEffects.js:339-494, packages/react-reconciler/src/ReactFiberCommitEffects.js:824-837, packages/react-reconciler/src/ReactFiberWorkLoop.js:4118-4125

How passive effects and cleanup fit

Passive mounts are traversed by commitPassiveMountOnFiber; function components with the Passive flag call commitHookPassiveMountEffects with HookPassive | HookHasEffect. The shared effect-list mount routine invokes each matching effect’s create function and records its returned cleanup function.

Passive cleanup uses the corresponding unmount path. commitPassiveUnmountEffects starts the traversal, and commitPassiveUnmountOnFiber invokes commitHookPassiveUnmountEffects for function components carrying passive work. When passive effects are disconnected, disconnectPassiveEffect runs passive cleanup before traversing child effects.

The timing is intentionally different from layout work: passive effects can be processed during commit or after paint. That separation lets the primary commit establish the host tree and layout observations before passive work is flushed.

Sources: packages/react-reconciler/src/ReactFiberCommitWork.js:3822-4434, packages/react-reconciler/src/ReactFiberCommitEffects.js:140-246, packages/react-reconciler/src/ReactFiberCommitWork.js:4834-4837, packages/react-reconciler/src/ReactFiberCommitWork.js:5099-5215, packages/react-reconciler/src/ReactFiberCommitWork.js:5267-5326, packages/react-reconciler/src/ReactFiberWorkLoop.js:4407-4415

How it connects

The commit phase receives the finished Fiber tree produced by Render Phase. Its tree traversal, flags, alternate links, and root state are the runtime structures described in Fiber Architecture.

Host mutations and mount operations hand off from the reconciler to renderer-specific host operations, such as commitHostMount, making ReactDOM Host Config the relevant renderer boundary.

Hook create and destroy functions, class lifecycles, refs, and passive cleanup are the runtime behavior covered in Effects & Lifecycle and useEffect & Cleanup.

Sources: packages/react-reconciler/src/ReactFiberCommitWork.js:3050-3065, packages/react-reconciler/src/ReactFiberCommitWork.js:2016-2033, packages/react-reconciler/src/ReactFiberCommitWork.js:599-931

Key takeaways

  • The primary commit order is before mutation, mutation, then layout; passive effects use a separate traversal.
  • Layout effects run after host mutation, so they can read the updated host tree.
  • Layout cleanup runs during mutation before layout effect creation.
  • Mutation work handles Fiber-driven host changes, including visibility and deletion paths.
  • Passive effects may run synchronously during commit or asynchronously after paint.

Sources: packages/react-reconciler/src/ReactFiberWorkLoop.js:3848-3850, packages/react-reconciler/src/ReactFiberWorkLoop.js:4118-4125, packages/react-reconciler/src/ReactFiberCommitEffects.js:113-138, packages/react-reconciler/src/ReactFiberCommitWork.js:1199-1211, packages/react-reconciler/src/ReactFiberCommitWork.js:1213-1260, packages/react-reconciler/src/ReactFiberCommitWork.js:1487-1844, packages/react-reconciler/src/ReactFiberWorkLoop.js:4407-4415

Want this for your repos?

Try Angada AI Wiki