What is the difference between useMemo and useCallback in React?
asked 2 months ago
1
13
I'm working on optimizing performance in a React application and came across useMemo and useCallback. I understand that both are used for memoization, but I'm confused about when to use each one.
From what I know:
useMemo memoizes a value
useCallback memoizes a function
However, I'm not sure how this affects re-renders in real-world scenarios.
For example, which one should I use for:
Preventing unnecessary re-renders of child components.
Optimizing expensive calculations inside a component.
Can you explain the difference with practical examples and when each should be preferred?
Both useMemo and useCallback are React Hooks used for performance optimization through memoization (caching). While they are similar, they serve completely different purposes in real-world scenarios.
Here is the quick distinction:
useMemo memoizes the result of a calculation (a value).
useCallback memoizes the function definition itself (a function reference).
Use useMemo when you want to avoid recalculating a value on every single render.
Your provided code is a perfect example of how this works:
How this affects re-renders:
Without useMemo: Every time you click "Toggle Theme", the App component re-renders, and the expensive function runs again, printing "Calculating..." to the console.
With useMemo: When you click "Toggle Theme", the App component still re-renders, but React sees that count hasn't changed. It skips the function execution and returns the cached expensiveValue. "Calculating..." is not logged.
Use useCallback when you pass callbacks to optimized child components (wrapped in React.memo) to prevent those children from re-rendering unless their props actually change.
In your provided code, useCallback was missing. Here is how your code should be corrected and optimized using useCallback:
How this affects re-renders:
In JavaScript, functions are objects, and objects are compared by reference.
Without useCallback: Every time App re-renders (e.g., when you click "Increment Count"), a brand new handleClick function is created in memory with a new reference address. Even though Child is wrapped in React.memo, it sees a "new" onClick prop and re-renders unnecessarily.
With useCallback: React caches the original function reference. When App re-renders, handleClick maintains the exact same memory reference. React.memo checks the props, sees that onClick has not changed, and prevents the Child component from re-rendering.
Key Summary
| Feature | useMemo | useCallback |
| :--- | :--- | :--- |
| What it returns | The return value of a function (e.g., 1000, ['array'], {object}). | The actual function itself (e.g., () => { ... }). |
| Primary Use Case | Optimizing expensive, CPU-intensive calculations. | Preventing unnecessary re-renders of memoized child components. |
| How it's written | const value = useMemo(() => computeValue(a), [a]); | const handler = useCallback(() => doSomething(a), [a]); |
1import { useState, useMemo } from "react";
2
3function App() {
4 const [count, setCount] = useState(0);
5 const [theme, setTheme] = useState("light");
6
7 // useMemo caches the result of the calculation
8 const expensiveValue = useMemo(() => {
9 console.log("Calculating...");
10 return count * 1000;
11 }, [count]); // Only recalculates when 'count' changes