DEV Community

Cover image for ๐Ÿง  Mastering useCallback in React: Prevent Unnecessary Re-Renders and Boost Performance
WebTechnology Tutorials
WebTechnology Tutorials

Posted on • Originally published at webcodingwithankur.blogspot.com

๐Ÿง  Mastering useCallback in React: Prevent Unnecessary Re-Renders and Boost Performance

Ever wondered why your child components keep re-rendering even when their props haven't changed? Or why performance drops in large React apps? The answer might lie in one powerful but underused hook โ€” useCallback.

In this blog post, weโ€™ll explore Reactโ€™s useCallback hook in depth. Youโ€™ll learn how it works, when to use it, and how to pair it with tools like React.memo, useState, and useMemo for real-world performance optimization.


๐Ÿ” What is useCallback in React?
useCallback is a React Hook that returns a memoized version of a callback function. It prevents the function from being re-created on every render โ€” unless the dependencies change.

const memoizedFn = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

Enter fullscreen mode Exit fullscreen mode

This becomes crucial when you're passing callbacks to memoized child components (React.memo), which rely on reference equality to avoid re-rendering.


๐Ÿง  Real-World Analogy
Think of your callback as a phone number. If it changes every time, the person you're calling (your child component) thinks it's someone new โ€” and answers again. useCallback keeps the number the same unless there's a real reason to change.


โœ… Why Use useCallback?

  • Prevent unnecessary re-renders
  • Improve app performance
  • Stabilize function references passed as props
  • Avoid expensive recalculations

โŒ Without useCallback

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

  const handleClick = () => {
    console.log("Clicked");
  };

  return (
    <>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <Child onClick={handleClick} />
    </>
  );
};

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

Enter fullscreen mode Exit fullscreen mode

Here, Child re-renders even when it doesnโ€™t need to โ€” because handleClick is recreated on every render.


โœ… With useCallback

const handleClick = useCallback(() => {
  console.log("Clicked");
}, []);

Enter fullscreen mode Exit fullscreen mode

Now the Child component wonโ€™t re-render unnecessarily, thanks to the stable function reference.


๐Ÿงช useCallback vs useMemo

| Hook          | Purpose                 | Returns                 |
| ------------- | ----------------------- | ----------------------- |
| `useCallback` | Memoizes a **function** | Same function reference |
| `useMemo`     | Memoizes a **value**    | Result of computation   |

Enter fullscreen mode Exit fullscreen mode
const memoizedCallback = useCallback(() => compute(a, b), [a, b]);
const memoizedValue = useMemo(() => compute(a, b), [a, b]);

Enter fullscreen mode Exit fullscreen mode

๐Ÿ” Debug With React DevTools
Use the Profiler in React DevTools to:

  • Inspect render frequency
  • Validate optimizations
  • Track function reference changes

โš™๏ธ Best Practices

โœ… Use with React.memo for child components
โœ… Use when function dependencies change infrequently
โœ… Avoid overuse โ€” it has memory overhead
โœ… Always pass accurate dependencies
โœ… Combine with useMemo when needed


๐Ÿ’ก Bonus: Working with useState

const [count, setCount] = useState(0);
const increment = useCallback(() => {
  setCount(prev => prev + 1);
}, []);
Enter fullscreen mode Exit fullscreen mode

๐Ÿ’ฌ Let's Connect
Have questions or want to share how you use useCallback? Drop a comment below or explore more tips on my blog:
๐Ÿ”— Mastering useCallback in React

Top comments (0)