Re-render Triggers
MedUnderstanding what causes React components to re-render is critical for performance and debugging. A component re-renders when its state changes, when its parent re-renders, or when a context it consumes changes. Knowing these triggers helps you prevent unnecessary renders.
Interactive Visualization
Key Points
- State change: calling setState with a new value triggers a re-render
- Parent re-render: all children re-render by default when a parent re-renders
- Context change: all consumers of a context re-render when the provider value changes
- Same state value: React bails out if the new state is the same reference (Object.is)
- Props alone do not trigger re-renders; the parent re-rendering does
- React.memo wraps a component to skip re-rendering when props have not changed
- forceUpdate in class components has no functional component equivalent
Code Examples
Identifying Re-render Causes
import { useState, memo } from 'react' function Parent() { const [count, setCount] = useState(0) const [name, setName] = useState('Alice') return ( <div> <button onClick={() => setCount((c) => c + 1)}> Count: {count} </button> {/* Re-renders on every count change even though it only uses name */} <Child name={name} /> {/* Skips re-render when name has not changed */} <MemoizedChild name={name} /> </div> ) } function Child({ name }: { name: string }) { return <div>Hello {name}</div> } const MemoizedChild = memo(function MemoizedChild({ name }: { name: string }) { return <div>Hello {name}</div> })
Child re-renders every time Parent re-renders regardless of which state changed; MemoizedChild skips re-rendering when its name prop has not changed
State Bailout
import { useState } from 'react' function Counter() { const [count, setCount] = useState(0) const handleClick = () => { // Setting the same value: React bails out, no re-render setCount(0) // No re-render if count is already 0 // New reference: always triggers re-render // setData({ ...data }) // Creates a new object, triggers re-render // setData(data) // Same reference, bails out } return <button onClick={handleClick}>Count: {count}</button> }
React uses Object.is to compare the new value with the current value; if they are the same, the re-render is skipped
Common Mistakes
- Creating new object or array references on every render that break memoization
- Assuming props changes cause re-renders when it is actually the parent re-rendering
- Placing rapidly changing state high in the tree causing the entire subtree to re-render
Interview Tips
- List the three triggers: state change, parent re-render, context change
- Explain why passing inline objects or functions as props breaks React.memo
- Discuss the composition pattern of moving state closer to where it is used