React UI Update Process: From Trigger to Commit
React updates the interface through a strict sequence: trigger → render → commit. During the render phase, React calculates the new virtual DOM tree without touching the actual DOM. The commit phase then applies changes synchronously. This separation enables performance optimization—especially in concurrent mode, where rendering can be interrupted based on priority.
Render Phase: Reconciliation and the Fiber Tree
The render phase builds a work-in-progress tree based on the current Fiber structure. A Fiber is a linked list of nodes representing the component hierarchy. Each node holds a reference to its previous version via the alternate property for diffing.
Reconciliation compares new React elements (from JSX) with the old ones. Stable key values ensure accurate matching, minimizing unnecessary updates.
This phase splits into two stages: beginWork (top-down) and completeWork (bottom-up):
- beginWork: Checks if rendering is necessary (bailout if not), calls the render function, sets flags (Placement, Update, Deletion), and recurses into children.
- completeWork: Finalizes a node after processing its children, aggregates subtree flags to optimize the commit.
Subtree flags propagate change information upward, skipping clean branches during commit.
| Flag | Description |
|------|-------------|
| Placement | Inserting a DOM node |
| Update | Updating attributes or text |
| Deletion | Removing an element |
| Ref | Handling refs |
| Layout | Scheduling useLayoutEffect |
| Passive | Scheduling useEffect |
Flags are set during render and executed during commit.
Commit Phase: DOM Mutation
The commit phase is synchronous and atomic, divided into three sub-phases:
- beforeMutation: Calls
getSnapshotBeforeUpdate(for class components) and cleans up old refs. - mutation: Applies the flags—inserting, updating, or removing DOM nodes.
- layout: Runs
componentDidMount/Update,useLayoutEffectsynchronously, updates refs, and schedulesuseEffect.
After layout, the browser takes over: style recalculation → layout/reflow → paint → composite. React doesn’t interfere with these steps.
Browser Pipeline After Commit
useEffect runs asynchronously, after paint—but for discrete events (click, keydown, input), it may execute before paint to maintain responsiveness.
Discrete events:
- click, keydown, input, submit
Continuous events (scroll, mousemove) always run after paint.
Concurrent Mode: Interruptible Rendering
In concurrent mode, rendering is broken into prioritized work units. High-priority updates (like typing) can interrupt low-priority ones (previous render), discarding the work-in-progress tree.
Commit remains unchanged: synchronous and single per update. This preserves DOM consistency.
Render can restart multiple times without a commit if updates are bailed out.
Key Takeaways
- Render computes changes in memory; DOM mutations happen only in commit when flags are present.
beginWork/completeWorkoptimize traversal using bailout and subtree flags.useLayoutEffectruns synchronously after mutation;useEffectruns asynchronously after paint.- Concurrent mode allows interrupting render, but commit remains indivisible.
- Stable keys are critical for efficient reconciliation.
— Editorial Team
No comments yet.