Performance optimization in React often brings up two hooks: useMemo and useCallback. These can help prevent unnecessary renders, but using them too early or in the wrong places can add needless complexity.

Let’s explore when these hooks actually make a difference—and how to use them effectively.


🚀 What do usememo and usecallback do?

Both hooks help memoize between renders:

  • useMemo caches the result of a function.
  • useCallback caches the function itself.

📦 Usememo: memoizing derived values

Use useMemo to avoid recalculating expensive values on every render. It only re-computes the value when its dependencies change.

const sortedList = useMemo(() => {
  return list.sort((a, b) => a.value - b.value);
}, [list]);

Use it when:

  • You're performing heavy calculations (e.g., sorting large datasets).
  • The computed value is passed as a prop to a child component that relies on referential equality.

🚫 Avoid it when:

  • The computation is cheap.
  • The memoized value isn't reused across renders.

🔁 Usecallback: memoizing functions

useCallback is useful when you want to avoid re-creating a function unless its dependencies change. It helps prevent unnecessary re-renders in child components that rely on function reference.

const handleClick = useCallback(() => {
  doSomething();
}, [doSomething]);

Use it when:

  • You're passing callback props to memoized child components (e.g., React.memo or useMemo).
  • The function is created inside a component that re-renders frequently.

🚫 Don’t use it just to "optimize"— in many cases, creating the function inline is cheaper and simpler.


🧪 Real example: without usecallback

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

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

  return <Child onClick={handleClick} />;
};

In this case, handleClick is recreated on every render, so if <Child /> is wrapped in React.memo, it will still re-render.

✅ With usecallback

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

Now handleClick is memoized and keeps the same reference unless dependencies change, which can help avoid unnecessary child renders.


🧱 Bonus: react.memo + usecallback

Combine React.memo and useCallback for optimal performance in components that rely on reference equality for props.

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


✅ Summary

HookPurposeUse When…
useMemoCache a computed valueValue is expensive or reused
useCallbackCache a function definitionPassing callbacks to memoized child

📌 Conclusion

useMemo and useCallback are powerful tools—but they’re not always necessary. Use them to solve specific performance issues, not as a default. Focus first on writing clean, readable code, and then optimize when profiling shows a real need.

Used wisely, these hooks can help your React app run smoother and feel snappier—especially at scale.