0
0
ReactDebug / FixBeginner · 4 min read

How to Prevent Unnecessary Re-renders in React Components

To prevent unnecessary re-renders in React, use React.memo to memoize functional components, and useCallback or useMemo hooks to memoize functions and values passed as props. Also, avoid creating new objects or functions inside components on every render unless needed.
🔍

Why This Happens

React re-renders a component whenever its props or state change. However, if you pass new objects or functions as props every time, React thinks the props changed even if the data is the same. This causes unnecessary re-renders, slowing down your app.

jsx
import React, { useState } from 'react';

const Child = ({ onClick }) => {
  console.log('Child rendered');
  return <button onClick={onClick}>Click me</button>;
};

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

  return (
    <div>
      <p>Count: {count}</p>
      <Child onClick={() => setCount(count + 1)} />
    </div>
  );
};

export default Parent;
Output
Child rendered Child rendered Child rendered ... (renders on every Parent render)
🔧

The Fix

Use useCallback to memoize the onClick function so it stays the same between renders unless dependencies change. Also, wrap Child with React.memo to skip re-rendering if props are unchanged.

jsx
import React, { useState, useCallback } from 'react';

const Child = React.memo(({ onClick }) => {
  console.log('Child rendered');
  return <button onClick={onClick}>Click me</button>;
});

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

  const handleClick = useCallback(() => {
    setCount(c => c + 1);
  }, [setCount]);

  return (
    <div>
      <p>Count: {count}</p>
      <Child onClick={handleClick} />
    </div>
  );
};

export default Parent;
Output
Child rendered Child rendered ... (renders only when count changes)
🛡️

Prevention

To avoid unnecessary re-renders in the future:

  • Use React.memo for functional components that receive props.
  • Memoize functions with useCallback and values with useMemo when passing them as props.
  • Avoid creating new objects or arrays inline in JSX props.
  • Keep state minimal and localize it to components that need it.
  • Use React Developer Tools to check component re-renders.
⚠️

Related Errors

Similar issues include:

  • Excessive re-renders: Caused by updating state inside render or effects without proper dependencies.
  • Stale closures: When memoized functions use outdated state values.
  • Prop drilling: Passing props deeply causing many components to re-render unnecessarily.

Quick fixes: use correct dependency arrays, lift state wisely, and use context or state management libraries.

Key Takeaways

Use React.memo to prevent re-rendering when props don't change.
Memoize callback functions with useCallback to keep their identity stable.
Avoid creating new objects or functions inline in JSX props.
Keep state minimal and localized to reduce re-render scope.
Use React DevTools to monitor and debug component renders.