React can reuse it
The element has a matching type and identity. React updates changed properties, attributes, event handlers, or text while leaving the rest in place.
React turns state changes into screen changes in stages: it calculates a new UI tree, matches that tree with the previous one, and then updates the DOM.
The words render and commit describe different work. Keeping them separate explains why a component can run without every DOM node being rebuilt.
After React commits, the browser can paint the result. Painting is browser work, not another React phase. On the first render there is no previous tree to match, so React creates the needed DOM. On later renders it can reuse matching parts.
During rendering, React calls the component whose update was triggered and, when needed, the components below it. Each component reads its current props, state, and context, then returns JSX. JSX describes the desired result; it does not directly edit the page.
name asks React to call Greeting again. The returned JSX describes the next heading.import { useState } from "react";
function Greeting() {
const [name, setName] = useState("Mira");
return (
<section>
<h2>Hello, {name}!</h2>
<button onClick={() => setName("Noah")}>
Greet Noah
</button>
</section>
);
}
Rendering must be pure. For the same inputs, a component should return the same JSX. Do not change the DOM, start a network request, or mutate an outside value while the component function runs. Event handlers and Effects provide places for those interactions.
Once React has a completed result, it commits only the DOM operations needed to make the page match it. In the greeting example, React can keep the existing <section>, <h2>, and <button>, then replace only the heading's text.
The element has a matching type and identity. React updates changed properties, attributes, event handlers, or text while leaving the rest in place.
The element's type or identity no longer matches. React removes the old DOM or component subtree and creates the new one.
A render does not guarantee a visible DOM change. If the calculated output is equivalent to what is already committed, React has nothing to mutate for that part of the page.
Reconciliation is React's matching process during rendering. React compares the new element tree with the previous one and decides which component instances and host elements can continue.
<p> can continue as the same paragraph, and a <Profile> can continue as the same component instance. Changed props and children are processed.<p> to <div>, or <Profile> to <Settings>, replaces that part of the tree and resets state below it.<p> keeps the same type, so React reuses it and updates its class and text.function SaveStatus({ isSaving }) {
return (
<p className={isSaving ? "saving" : "saved"}>
{isSaving ? "Saving changes…" : "All changes saved"}
</p>
);
}
Reconciliation is why “render again” does not mean “rebuild the whole DOM.” Component output is recalculated first; DOM work follows from the differences React finds.
State setters queue updates. Batching lets React wait until the current interaction has finished, process related queued updates together, and usually produce one render and one commit for the batch. This avoids showing an intermediate screen such as a new selection with an old details panel.
function ContactPicker() {
const [contactId, setContactId] = useState(1);
const [isEditing, setIsEditing] = useState(true);
function selectContact(nextId) {
setContactId(nextId);
setIsEditing(false);
}
return (
<button onClick={() => selectContact(2)}>
Open contact 2
</button>
);
}
Connection to state queues: batching changes when React processes related requests, not what each setter means. If several updates depend on pending state, functional updates are still required. React may also restart or repeat rendering before a commit, so component code must stay pure.
A component instance keeps its state when React can match the same component type in the same place under its parent, with the same key when one is present. This page focuses on identity as an input to reconciliation; the preserving-state notes use the same rule to explain what happens to state.
TaskRow to the same task after sorting.function TaskList({ tasks }) {
const sortedTasks = [...tasks].sort((a, b) =>
a.title.localeCompare(b.title)
);
return (
<ul>
{sortedTasks.map(task => (
<TaskRow key={task.id} task={task} />
))}
</ul>
);
}
Keep this model: updates trigger work; rendering calculates; reconciliation matches identities; committing mutates the DOM. Batching lets related updates travel through that pipeline together.
No. Rendering calculates the desired UI. If reconciliation finds that the committed DOM already matches, no DOM mutation is needed for that part.
React batches related updates from the interaction, processes their queues together, and can render and commit the completed result instead of committing each intermediate state.
A stable key tied to the item's data lets reconciliation match that item with its previous component instance, even at a different sibling position.