React · Topic 1 of 8
Rendering and reconciliation
What you will learn
Every update runs in two phases: a pure render that computes what the UI should look like, and a commit that applies it to the DOM. Reconciliation decides, by element type, position, and key, which existing instances to keep and which to reset.
Render vs commit
Render means React calls your components to get a tree of elements. It must be pure, and React may run it more than once, pause it, or throw it away.
Commit is the part that touches the DOM, attaches refs, and runs layout effects. It is synchronous. Passive effects from useEffect usually follow after paint.
Elements are just objects
JSX creates plain objects with a type, props, and key. They describe the UI and cost almost nothing to create. React compares the new tree of descriptions with the previous one to decide what to change.
If an element has the exact same reference as last time, React can skip that subtree entirely.
Identity is type plus position
At each position, same type means update the existing instance and keep its state. Different type means tear down the subtree and mount a new one.
This is why defining a component inside another component remounts it every render: its type is a new function each time.
Example
Identity is type plus position
function Parent() {
// BAD: new type every render
const Row = () => <input />;
return <Row />;
}Keys control identity in lists
Within siblings, keys match items across renders so state moves with the data. Use stable ids, not indexes, when lists can reorder, insert, or delete.
Keys also work outside lists. Changing a key forces a fresh instance, which is the cleanest way to reset state.
Example
Keys control identity in lists
<Profile key={userId} userId={userId} />Batching and priority
React batches all updates from the same tick into one render, whether they come from events, timeouts, or promises. State is a snapshot, so setN(n + 1) three times still adds one.
startTransition and useDeferredValue mark work as low priority and interruptible, so urgent input renders first. Use flushSync only when you must read the DOM right away.
Key points
- Render is pure and can be repeated or discarded; commit mutates the DOM.
- Children re-render with their parent unless bailed out via memo or an identical element reference.
- Same type at the same position keeps state; a different type resets it.
- Use stable unique keys; change a key to deliberately reset a subtree.
- Updates are batched automatically, and state inside a render is a snapshot.
Common mistakes
- Declaring components inside other components, which remounts them on every render.
- Using array index as key in lists that reorder or change.
- Mutating variables, refs, or the DOM during render.
- Passing inline objects or functions to memo components and expecting memo to help.
- Assuming state updates apply immediately instead of on the next render.
Lesson complete
Ready to check what you learned?
Swipe left or right, or use the buttons.