DEV Community

Cover image for When Does a Component Re-render in React?
Mía Salazar
Mía Salazar

Posted on

When Does a Component Re-render in React?

React's declarative nature and virtual DOM abstraction make it deceptively easy to build complex UIs. However, understanding when and why a component re-renders is essential for performance, especially in larger applications. Re-renders can be cheap, but unnecessary ones add up.

This article explains the most common triggers of component re-renders and offers strategies for controlling them effectively.

What Triggers a Re-render?

When a component’s state changes using useState, React schedules a re-render of that component.

Every call to setCount with a different value will cause the component to re-render.

const [count, setCount] = useState(0);

const increment = () => setCount(count + 1);
Enter fullscreen mode Exit fullscreen mode

Prop Changes

If a component receives new props (i.e., if the parent re-renders and passes new values), the child will also re-render by default.

If someValue changes (even if it’s deeply equal but a new reference), MyComponent will re-render.

<MyComponent data={someValue} />
Enter fullscreen mode Exit fullscreen mode

Context Changes

React Contexts provide a way to share values across the component tree. Any update to a context value will re-render all consuming components.

When theme changes, ChildComponent and all others using useContext(MyContext) re-render.

<MyContext.Provider value={theme}>
  <ChildComponent />
</MyContext.Provider>
Enter fullscreen mode Exit fullscreen mode

Parent Re-renders

Even if a child’s props didn’t change, it can re-render if its parent re-renders unless it’s memoised with React.memo.

React Reconciliation: How React Decides to Re-render

React uses referential equality (===) to compare props and state. If something changes, a new object, array, or primitive, it assumes the UI might need to update.

This is why using immutable patterns is crucial. Mutating objects without changing their reference can lead to bugs or skipped renders.

How to Prevent Unnecessary Re-renders

Use React.memo for Pure Functional Components

Only re-renders if name changes.

const MyComponent = React.memo(({ name }) => {
  console.log("Rendered!");
  return <div>{name}</div>;
});
Enter fullscreen mode Exit fullscreen mode

Use useCallback and useMemo to Stabilise Functions and Values

Without useCallback, the function is recreated on every render and may cause children to re-render unnecessarily.

const handleClick = useCallback(() => {
  // Do something
}, []);
Enter fullscreen mode Exit fullscreen mode

Avoid Inline Objects and Arrays in Props

// Causes re-render
<Component data={{ a: 1 }} />

// Use useMemo
const data = useMemo(() => ({ a: 1 }), []);
<Component data={data} />
Enter fullscreen mode Exit fullscreen mode

Keep State Local Where Possible

Lifting state up or storing too much in global context can lead to unnecessary tree-wide re-renders. Keep state close to where it’s used.

Conclusion

Understanding when React re-renders a component is vital to building performant and predictable interfaces. State, props, context, and parent updates are the primary causes. By embracing immutable patterns and using tools like React.memo, useCallback, and useMemo, you can significantly reduce unnecessary rendering and boost the responsiveness of your application.

Top comments (0)