DEV Community

Cover image for What actually causes React to re-render
Nikhil Dabhade
Nikhil Dabhade

Posted on

What actually causes React to re-render

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>;
}
Enter fullscreen mode Exit fullscreen mode

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:

  1. React calls your component function.
  2. It produces a new React element tree.
  3. React compares it with the previous tree (reconciliation).
  4. 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 />;
}
Enter fullscreen mode Exit fullscreen mode

When Parent re-renders:

Parent()
Child()
Enter fullscreen mode Exit fullscreen mode

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>;
});
Enter fullscreen mode Exit fullscreen mode

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} />;
}
Enter fullscreen mode Exit fullscreen mode

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} />;
}
Enter fullscreen mode Exit fullscreen mode

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} />;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

But this only happens in development environment not in production.

5. Context

<ThemeContext.Provider value={theme}>
Enter fullscreen mode Exit fullscreen mode

When the value changes,

const theme = useContext(ThemeContext);
Enter fullscreen mode Exit fullscreen mode

Every component consuming that context re-renders.

6. External Store Updates

Libraries (Redux, Zustand) using:

useSyncExternalStore()
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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)