What are the three phases of React’s update cycle?
Trigger → Render → Commit. A state update triggers a render, React calls your component functions (render phase), then applies the minimal DOM changes (commit phase).
What two things can trigger a render?
1) Initial render (createRoot + render call). 2) A state update in any component (calling a setState function). Props alone don’t trigger renders — the parent’s re-render does.
What actually happens during the ‘render phase’?
React calls your component function, which returns JSX. This is recursive — if that component renders child components, React calls those too, building a complete tree of what should be on screen.
What happens during the ‘commit phase’?
React compares the new render result with the previous one and applies the minimal set of actual DOM mutations. If nothing changed, React touches nothing. The commit phase is synchronous.
Why is ‘rendering’ not the same as ‘updating the DOM’?
Rendering = calling your component function to get JSX. Committing = applying changes to the DOM. React may render a component and then discover nothing changed, so it commits nothing.
When a component re-renders, which of its children also re-render?
All of them, by default. When a parent re-renders, React re-renders every child in its subtree — even if the child’s props haven’t changed. This is why React.memo exists.
What does ‘state as a snapshot’ mean?
Each render captures a frozen snapshot of state. All variables, event handlers, and JSX in that render use the state values from when the render began — they can’t see future updates.
Why does logging state right after setState show the old value?
Because state is a snapshot. The setState call schedules a new render with the updated value, but the current closure still holds the old snapshot. The new value only exists in the next render.
What happens if you call setCount(count + 1) three times in a row?
All three read the same snapshot of count. If count was 0, all three schedule setCount(1). Result: count becomes 1, not 3. Each call uses the same stale snapshot.
How do you fix the triple-setState problem to get count + 3?
Use the updater function form: setCount(prev => prev + 1) three times. Each updater receives the latest pending value, so they chain correctly: 0→1→2→3.
What is state batching?
React groups multiple setState calls within the same event handler (or tick in React 18+) into a single re-render. This prevents unnecessary intermediate renders.
Does React batch state updates inside async code (setTimeout, fetch .then)?
In React 18+, yes — all updates are automatically batched regardless of where they originate. In React 17 and earlier, only updates inside React event handlers were batched.
What causes an infinite render loop?
Calling setState unconditionally during render — e.g. setCount(count + 1) at the top level of a component body, or calling a function that sets state in JSX like onClick={handleClick()} with parentheses.
What is reconciliation?
React’s process of comparing the new virtual DOM tree with the previous one to determine the minimal set of DOM operations needed. It uses a diffing algorithm to make this efficient.
How does React’s diffing algorithm work at a high level?
It compares trees level by level. Different element types = destroy and rebuild. Same type = update props in place. For lists, it uses keys to match items across renders.
Why are keys critical for list rendering performance?
Keys let React match list items across renders. Without keys (or with index keys on reorderable lists), React may recreate items unnecessarily or reuse the wrong component instances.
What is the virtual DOM?
A lightweight JavaScript representation of the actual DOM. React renders to this virtual tree first, diffs it against the previous version, then commits only the real DOM changes needed.
Does React re-render the whole app on every state change?
No. Only the component whose state changed and all of its descendants re-render. Siblings and ancestors are unaffected (unless they consume the same context or state).
What is a ‘wasted render’?
When React calls a component’s function but the output is identical to the previous render, so no DOM changes are committed. The render phase work was unnecessary.
How can you see which components re-render and why?
Use the React DevTools Profiler. It shows each commit, which components rendered, how long they took, and what triggered the render (state change, parent re-render, or context change).