What Causes Re-render in React: Key Reasons Explained
In React, a component re-renders when its
state or props change, or when its parent component re-renders. Also, changes in context or forced updates with forceUpdate() cause re-renders.Syntax
React components re-render automatically when their state or props change. You update state using the useState hook in functional components. Props are passed from parent to child components.
Example syntax for updating state:
const [count, setCount] = useState(0);
When you call setCount(newValue), React schedules a re-render.
jsx
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); } export default Counter;
Example
This example shows a parent component passing a prop to a child. When the parent's state changes, it causes both the parent and child to re-render.
jsx
import React, { useState } from 'react'; function Child({ message }) { console.log('Child rendered'); return <p>Message: {message}</p>; } function Parent() { const [count, setCount] = useState(0); console.log('Parent rendered'); return ( <div> <Child message={`Count is ${count}`} /> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); } export default Parent;
Output
When clicking the button:
Parent rendered
Child rendered
The page updates to show the new count value.
Common Pitfalls
1. Updating state with the same value: React may skip re-render if state value does not change.
2. Passing new object or function props every render: This causes child components to re-render unnecessarily.
3. Forgetting to memoize expensive components: Use React.memo to avoid unwanted re-renders.
jsx
import React, { useState, useCallback } from 'react'; const Child = React.memo(({ onClick }) => { console.log('Child rendered'); return <button onClick={onClick}>Click me</button>; }); function Parent() { const [count, setCount] = useState(0); // Without useCallback, onClick is a new function each render const handleClick = useCallback(() => { setCount(c => c + 1); }, [setCount]); console.log('Parent rendered'); return <Child onClick={handleClick} />; } export default Parent;
Output
Clicking the button:
Parent rendered
Child rendered (only once, thanks to React.memo and useCallback)
Quick Reference
| Cause | Description |
|---|---|
| State change | Calling state setter like setState or setCount triggers re-render. |
| Props change | When parent passes new or changed props, child re-renders. |
| Context change | When React context value changes, consuming components re-render. |
| Parent re-render | If parent re-renders, child re-renders unless memoized. |
| forceUpdate() | Manually forces a component to re-render. |
Key Takeaways
React re-renders components when their state or props change.
Passing new objects or functions as props causes child re-renders unless memoized.
Use React.memo and useCallback to optimize and avoid unnecessary re-renders.
Context changes also trigger re-renders in consuming components.
Parent re-renders cause child re-renders unless prevented by memoization.