In React, useMemo is a hook used to memoize a value, which means it remembers the result of a computation so it doesn’t have to be recalculated unless necessary. This is useful for optimizing performance, especially when you have expensive calculations that don’t change often.
How useMemo Works:
useMemo takes two arguments:
- A function that returns the value you want to memoize.
- A dependency array that tells React when to recalculate the value. If the values in this array haven't changed, React will return the memoized value without recalculating it.
Example: Without useMemo
In this example, every time the button is clicked, the slowFunction is executed, which is a performance issue because it's a long-running calculation.
import { useState, useCallback } from 'react';
import { data } from '../../../../data';
import List from './List';
const slowFunction = () => {
let value = 0;
for (let i = 0; i <= 1000000000; i++) {
value += i;
}
return value;
};
const App = () => {
const [people, setPeople] = useState(data);
const [count, setCount] = useState(0);
const value = slowFunction();
console.log(value); // The slow function runs on each click
const removePerson = useCallback(
(id) => {
const newPeople = people.filter((person) => person.id !== id);
setPeople(newPeople);
},
[people]
);
return (
<section>
<button
className="btn"
onClick={() => setCount(count + 1)}
style={{ marginBottom: '1rem' }}
>
count {count}
</button>
<List people={people} removePerson={removePerson} />
</section>
);
};
export default App;
Issue: Every time the count changes, the slowFunction runs, even though the result doesn’t change. This can cause performance problems.
Example: With useMemo
We can use useMemo to ensure that the slowFunction only runs once, unless the dependencies change (in this case, there are no dependencies, so it runs only once on the initial render).
import { useState, useMemo } from 'react';
import { data } from '../../../../data';
import List from './List';
const slowFunction = () => {
let value = 0;
for (let i = 0; i <= 1000000000; i++) {
value += i;
}
return value;
};
const App = () => {
const [people, setPeople] = useState(data);
const [count, setCount] = useState(0);
const value = useMemo(() => slowFunction(), []);
// OR const value = useMemo(slowFunction, []);
console.log(value); // Now the slow function runs only once
const removePerson = (id) => {
const newPeople = people.filter((person) => person.id !== id);
setPeople(newPeople);
};
return (
<section>
<button
className="btn"
onClick={() => setCount(count + 1)}
style={{ marginBottom: '1rem' }}
>
count {count}
</button>
<List people={people} removePerson={removePerson} />
</section>
);
};
export default App;
What Changed:
- We wrapped the
slowFunctioncall insideuseMemo, which will only execute once, when the component first renders. - The slow function result is now memoized, so it doesn't need to be recalculated on every re-render, improving performance.
Summary of useMemo
- Purpose: To memoize expensive calculations and avoid unnecessary recomputations.
- Arguments:
- The function that returns the value you want to memoize.
- The dependency array that controls when the memoized value should be recalculated.
- Performance Boost: It prevents recalculating values on every render, especially when the dependencies haven’t changed.


Top comments (1)
useCallbackvsuseMemouseCallbackis used to memoize a function, ensuring that the function reference remains the same between renders unless its dependencies change. It's useful when passing functions to child components to avoid unnecessary re-renders.useMemois used to memoize the result of a computation (the value returned by a function). It's useful when you want to avoid expensive recalculations unless specific dependencies change.In short:
useCallbackwhen you need to memoize a function.useMemowhen you need to memoize a computed value.