Most React developers think that React only re-renders because we have done some state update and while it is true, it's not the only reason behind it.
Render ≠ DOM Updates
First, we need to understand what a render actually means in React.
Render !== DOM Updation
Render does not mean DOM updates, a component can re-render multiple times without any DOM update.
function Counter() {
console.log("rendered");
return <h1>Counter</h1>;
}
Even though the above example doesn't have any state or props still it can re-render while DOM remains unchanged.
What Actually Happens During a Render?
So now the question arises, what actually is render in react?
Render is the process where:
- React calls your component function.
- It produces a new React element tree.
- React compares it with the previous tree (reconciliation).
- Only necessary DOM updates are applied (e.g. Component is using any state which changed) or no DOM updates.
Common Reasons React Re-renders
1. Parent Re-renders Cause Child Re-renders
function Parent() {
const [count, setCount] = useState(0);
return <Child />;
}
When Parent re-renders:
Parent()
Child()
both execute again, Even if Child receives no props.
How to prevent the child from re-render?
const Child = React.memo(function Child() {
console.log("Child render");
return <div>Child</div>;
});
Just wrap it with React memo.
2. Props Changes
When count changes Child receives new props and re-renders.
function Parent() {
const [count, setCount] = useState(0);
return <Child count={count} />;
}
3. Functions and Objects Cause Extra Re-renders
Even though we have wrapped our child with React memo still it will cause re-render if we pass functions and objects.
function Parent() {
const [count, setCount] = useState(0);
const handleClick = () => {
console.log("clicked");
}
return <Child onClick={handleClick} />;
}
Because the memo only compares the reference of the old and new function (or object), this is called shallow compare.
If a memoized child receives functions or objects as props, useCallback and useMemo can help preserve references and avoid unnecessary re-renders.
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log("clicked");
}, []);
return <Child onClick={handleClick} />;
}
Now it will not cause extra re-renders
4. Strict Mode
In strict mode React intentionally invokes component render logic twice to help detect side effects.
<React.StrictMode>
But this only happens in development environment not in production.
5. Context
<ThemeContext.Provider value={theme}>
When the value changes,
const theme = useContext(ThemeContext);
Every component consuming that context re-renders.
6. External Store Updates
Libraries (Redux, Zustand) using:
useSyncExternalStore()
I've explained this here in detail.
7. State Updates
The most obvious action which causes React to re-render
const [count, setCount] = useState(0);
setCount(count + 1);
But if the value doesn't change, React may not call the component again (at least in case of primitive types).
Check if the same object or array will cause the re-render or not.
React re-renders are not totally bad. Rendering is simply React calling your component function again. The real cost comes from expensive computations, large component trees, and unnecessary DOM updates. Before using React.memo, useMemo, or useCallback, make sure a re-render is actually causing a big performance problem.
Top comments (0)