How to Update Reconciliation in React
This article explains how React handles updates through its reconciliation process, detailing how the Virtual DOM identifies changes and updates the user interface efficiently. You will learn about the diffing algorithm, the role of keys in list rendering, and how components trigger updates to keep the browser DOM in sync with your application state.
Understanding Reconciliation in React
Reconciliation is the process through which React updates the browser DOM. When a component’s state or props change, React creates a new tree of React elements. It then compares this new tree with the previous one to determine the most efficient way to update the real DOM. This comparison is done using a highly optimized heuristic algorithm called the “diffing algorithm.”
How React Triggers a Reconciliation Update
You do not directly manipulate the reconciliation process; instead, you trigger it by changing the application state. React schedules an update whenever:
- State Changes: Calling a state updater function
from
useStateorthis.setStatein class components. - Props Change: When a parent component passes new props down to a child component.
- Context Changes: When a value in a React Context provider changes, causing consuming components to re-render.
Once an update is triggered, React begins the diffing process to calculate the differences between the old Virtual DOM and the new Virtual DOM.
The Diffing Algorithm Rules
To compare two trees, React first compares the root elements. The behavior depends on the types of these elements:
1. Elements of Different Types
If the root elements of the old and new trees are of different types
(for example, swapping a <div> for a
<span>, or a <Header> for a
<Footer>), React will tear down the old tree
completely.
- The old DOM nodes are destroyed.
- Component instances receive
componentWillUnmount(). - The new DOM nodes are inserted into the DOM.
- Any state associated with the old component tree is lost.
2. DOM Elements of the Same Type
When comparing two React DOM elements of the same type (for example,
two <div> elements), React looks at the attributes of
both. It keeps the underlying DOM node and only updates the changed
attributes, such as classes, styles, or custom data attributes.
// Before
<div className="before" title="stuff" />
// After
<div className="after" title="stuff" />In this scenario, React only updates the className on
the DOM node, leaving the rest of the element untouched.
3. Component Elements of the Same Type
When a component updates, the component instance stays the same, maintaining its state across renders. React updates the props of the underlying component instance to match the new element and calls lifecycle methods (or triggers hooks) accordingly. Next, the render method is called, and the diffing algorithm recurses on the previous result and the new result.
Optimizing Reconciliation with Keys
When recursing on the children of a DOM node, React iterates over
both lists of children at the same time and generates a mutation
whenever there is a difference. To do this efficiently, especially when
inserting, deleting, or reordering items, React requires a
key prop.
Without keys, reordering a list causes React to mutate every single child element because it cannot match the identity of the old elements with the new ones.
// With unique keys, React knows exactly which elements moved, added, or removed
<ul>
<li key="user-1">Alice</li>
<li key="user-2">Bob</li>
</ul>Using unique and stable keys (like IDs from a database instead of array indexes) allows React to match children across renders, drastically reducing the number of DOM writes and preserving local component state.