Render vs Commit
React splits updates into two distinct phases. Understanding the boundary helps you predict when side effects run and when the DOM actually changes.
The Render phase is pure and may be interrupted — React calls your component functions and builds a new virtual DOM tree. The Commit phase is synchronous and side-effect safe — React applies the minimal set of DOM mutations, then fires useLayoutEffect and useEffect.
Virtual DOM & Diffing
React maintains a lightweight in-memory representation of the UI called the Virtual DOM. On each render, React diffs the new tree against the previous one to compute the minimal DOM changes needed.
When Does React Re-render?
A component re-renders whenever React needs to check if its output has changed. Knowing the exact triggers prevents unnecessary renders and state bugs.
// Re-render triggers
// 1. State change
const [count, setCount] = useState(0);
setCount(1); // triggers re-render
// 2. Props change
<MyComponent value={newValue} /> // parent re-renders → child re-renders
// 3. Context change
const theme = useContext(ThemeContext); // re-renders when context value changes
// Prevent unnecessary re-renders
const MemoComponent = React.memo(MyComponent);
const value = useMemo(() => expensive(a, b), [a, b]);
const handler = useCallback(() => doSomething(), []);Optimization Tips
Most React apps do not need aggressive memoization. Start by profiling, then apply targeted fixes. Over-optimizing untouched code is a common source of bugs.
useMemo and useCallback has a memory and bookkeeping cost. Measure with React DevTools Profiler first — if a component is not a measured bottleneck, leave it alone.