When to use useCallback, useMemo and useEffect ?
Last Updated :
09 Jan, 2025
The useCallback hook is used to memoize the functions to prevent unnecessary re-renders, while useMemo is used to memoize the computed outputs, and useEffect performs sideEffects in a React application.
The useCallback, useMemo, and useEffect are used to optimize the performance and manage the side effects of React-based applications between rerendering of the functional components. To answer when to use useCallBack, useMemo, and useEffect, we should know what exactly they do and how they are different.
Prerequisites:
useCallback
The useCallback is a react hook that returns a memoized callback when passed a function and a list of dependencies as parameters. It's very useful when a component is passing a callback to its child component to prevent the rendering of the child component. It only changes the callback when one of its dependencies gets changed.
useMemo
The useMemo is similar to useCallback hook as it accepts a function and a list of dependencies but it returns the memoized value returned by the passed function. It recalculated the value only when one of its dependencies change. It is useful to avoid expensive calculations on every render when the returned value is not going to change.
useEffect
The useEffect hook that helps us to perform mutations, subscriptions, timers, logging, and other side effects after all the components has been rendered. The useEffect accepts a function that is imperative in nature and a list of dependencies. When its dependencies change it executes the passed function.
Steps to create React application for understanding all the three hooks
Step 1: Create a React application using the following command:
npx create-react-app usecallbackdemo
Step 2: After creating your project folder i.e. foldername, move to it using the following command:
cd usecallbackdemo
Project Structure:
The project structureThe updated Dependencies in package.json file will look like:
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
Now let's understand the working of all three hooks
1. usecallback:
It depends on referential equality. In javascript, functions are first-class citizens, meaning that a function is a regular object. Hence, two function objects even when they share the same code are two different objects. Just remember that a function object is referentially equal only to itself.
Example: Write the following code in App.js and List.js file
JavaScript
//App.js
import React, { useState } from "react"
import List from "./List"
function App() {
{/* Initial states */ }
const [input, setInput] = useState(1);
const [light, setLight] = useState(true);
{/* getItems() returns a list of number which
is number+10 and number + 100 */}
const getItems = () => {
return [input + 10, input + 100];
}
{/* Style for changing the theme */ }
const theme = {
backgroundColor: light ? "White" : "grey",
color: light ? "grey" : "white"
}
return <>
{/* set the theme in the parent div */}
<div style={theme}>
<input type="number"
value={input}
{/* When we input a number it is store in our stateful variable */}
onChange={event => setInput(parseInt(event.target.value))} />
{/* on click the button the theme is set to the
opposite mode, light to dark and vice versa*/}
<button onClick={() => setLight(prevLight => !prevLight)}>
{light ? "dark mode" : "light mode"}
</button>
<List getItems={getItems} />
</div>
</>;
}
export default App;
JavaScript
//List.js
import React, { useEffect, useState } from "react"
function List({ getItems }) {
/* Initial state of the items */
const [items, setItems] = useState([]);
/* This hook sets the value of items if
getItems object changes */
useEffect(() => {
console.log("Fetching items");
setItems(getItems());
}, [getItems]);
/* Maps the items to a list */
return <div>
{items.map(item => <div key={item}>{item}</div>)}
</div>
}
export default List;
Step to run the application:
npm start
Output:The list component gets the getItems function as a property. Every time the getItems function object changes useEffect will call setItems to set the list returned from the function object to stateful variable items and then we map those items into a list of div.Every time items are fetch using getItems in useEffect, we print "Fetching items" to see how often the items are fetched.

Now the weird thing is, when we press the button to change the theme, we see that the items are still being fetched even when the input field is not modified because it is called every time the component is re-rendered.
Solution: Using useCallback
JavaScript
//App.js
import React, { useCallback, useState } from "react"
import List from "./List"
function App() {
{/* Initial states */ }
const [input, setInput] = useState(1);
const [light, setLight] = useState(true);
{/* useCallback memoizes the getItems() which
returns a list of number which is number+10
and number + 100 */}
const getItems = useCallback(() => {
return [input + 10, input + 100];
}, [input]);
{/* style for changing the theme */ }
const theme = {
backgroundColor: light ? "White" : "grey",
color: light ? "grey" : "white"
}
return <>
{/* set the theme in the parent div */}
<div style={theme}>
<input type="number"
value={input}
{/* When we input a number it is stored in
our stateful variable */}
onChange={event =>
setInput(parseInt(event.target.value))
} />
{/* on click the button the theme is set to
the opposite mode, light to dark and vice versa*/}
<button onClick={() =>
setLight(prevLight =>
!prevLight)}>{light ? "dark mode" : "light mode"}
</button>
<List getItems={getItems} />
</div>
</>;
}
export default App;
Output:

2. useMemo:
The useMemo hook returns a memoised value after taking a function and a list of dependencies. It returns the cached value if the dependencies do not change. Otherwise, it will recompute the value using the passed function.
Example: Doing heavy calculation without useMemo
JavaScript
//App.js
import React, { useState } from 'react';
const WithoutMemo = () => {
const [count, setCount] = useState(0);
const [renderCount, setRenderCount] = useState(0);
const computeExpensiveValue = (num) => {
console.log("Computing...");
let result = 0;
for (let i = 0; i < 1000000000; i++) {
result += num;
}
return result;
};
const result = computeExpensiveValue(count);
// This component re-renders on every count change,
// causing the expensive function to run again
return (
<div>
<h2>Without Memo Example</h2>
<p>Count: {count}</p>
<p>Result: {result}</p>
<p>Render Count: {renderCount}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<button onClick={() => setRenderCount(renderCount + 1)}>
Increment Render Count
</button>
</div>
);
};
export default WithoutMemo;
Output:
Here we can see that it is taking too much time to calculate the result when rendered.
Solution: Using UseMemo
JavaScript
//App.js
import React, { useState, useMemo } from 'react';
const WithMemo = () => {
const [count, setCount] = useState(0);
const [renderCount, setRenderCount] = useState(0);
const computeExpensiveValue = (num) => {
console.log("Computing...");
let result = 0;
for (let i = 0; i < 1000000000; i++) {
result += num;
}
return result;
};
// Using useMemo to memoize the result based on count
const result = useMemo(() => computeExpensiveValue(count), [count]);
return (
<div>
<h2>With Memo Example</h2>
<p>Count: {count}</p>
<p>Result: {result}</p>
<p>Render Count: {renderCount}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<button onClick={() => setRenderCount(renderCount + 1)}>
Increment Render Count
</button>
</div>
);
};
export default WithMemo;
Output:

Explanation: Here we can see when clicking on "Increment render count" component without useMemo takes too much time.
3. useEffect:
In react, side effects of some state changes are not allowed in functional components. To perform a task once the rendering is complete and some state changes, we can use useEffect. This hook takes a function to be executed and a list of dependencies, changing which will cause the execution of the hook's body.
Example:
JavaScript
//App.js
import React, { useEffect, useState } from "react"
function App() {
/* Some data */
const data = {
Colors: ["red", "green", "yellow"],
Fruits: ["Apple", "mango", "Banana"]
}
/* Initial states */
const [currentChoice, setCurrentChoice] = useState("Colors");
const [items, setItems] = useState([]);
/* Using useEffect to set the data of currentchoice
to items and console log the fetching... */
useEffect(() => {
setItems(data[currentChoice]);
console.log("Data is fetched!");
}, [currentChoice]);
return <>
<button onClick={() => setCurrentChoice("Colors")}>Colors</button>
<button onClick={() => setCurrentChoice("Fruits")}>Fruits</button>
{items.map(item => { return <div key={item}>{item}</div> })}
</>;
}
export default App;
Output:

Explanation: When the application loads for the first time, data is fetched from our fake server. This can be seen in the console in the image below. And when we press the Fruits button, appropriate data is again fetched from the server and we can see that "Data is fetched" is again printed in the console. But if we press the colors button again and again, we don't have to get the data from the server again as our choice state does not change.
Conclusion
Hence,
- useCallback hook should be used when we want to memoize a callback function, and
- we can use useMemo to memoize the result of a function to avoid expensive computation
- useEffect is used to produce side effects to some state changes.
One thing to remember is that one should not overuse hooks.
Similar Reads
When should we use the useEffect hook?
The useEffect hook in React is used to perform side effects in functional components. Side effects are actions that happen outside of the normal flow of the component, such as fetching data from an API, subscribing to events, or updating the DOM. When should we use the useEffect hook?Data Fetching:I
2 min read
Optimizing Performance with useMemo and useCallback Hooks
In React applications, optimizing performance is crucial for ensuring smooth user experiences, especially in components with complex computations or frequent re-renders. Two hooks provided by React, useMemo, and useCallback, offer efficient ways to achieve performance improvements by memoizing value
4 min read
How To Avoid Infinite Loops When Using useEffect() in ReactJS?
useEffect() can lead to infinite loops, causing performance issues or crashes if not used correctly. In this article, we will explain what causes these infinite loops and how to avoid them when working with useEffect() in ReactJS.Avoid infinite loops in useEffect() by providing appropriate dependenc
4 min read
Handling Error using React useState and useEffect Hooks
In React, handling error states is very important to provide a smooth user experience and handle unexpected errors that may occur during data fetching or asynchronous operations. By using the useState and useEffect hooks, you can easily manage error states in your React applications. In this article
3 min read
When to use React.memo() over useMemo() & vice-versa ?
React provides us with powerful tools to optimize the performance of our applications. Two such tools are `React.memo()` and `useMemo()`, which serve similar yet distinct purposes. In this article, we'll explore when to use `React.memo()` over `useMemo()` and vice versa, along with syntax and code e
4 min read
What is useLayoutEffect, and how is it different from useEffect?
`useLayoutEffect` runs synchronously right after all DOM changes, which makes it perfect for tasks that need access to the DOM before any visual updates occur, like measuring element size or position. On the other hand, `useEffect` runs asynchronously after the browser has finished painting changes,
2 min read
How do you use multiple useEffect in a component?
useEffect is a hook used to perform side effects in function components. If you need to use multiple useEffect hooks in a single component, you can simply place them one after the other within your component function. Key Points for Using Multiple useEffect Hooks:Separation of Concerns: Each useEffe
2 min read
Fetching Data from an API with useEffect and useState Hook
In modern web development, integrating APIs to fetch data is a common task. In React applications, the useEffect and useState hooks provide powerful tools for managing asynchronous data fetching. Combining these hooks enables fetching data from APIs efficiently. This article explores how to effectiv
4 min read
Difference Between useState and useEffect Hook in ReactJS
ReactJS is the powerful JavaScript library used for building user interfaces especially single-page applications(SPAs). Two of the most commonly used hooks in React are useState and useEffect. These hooks make functional components more powerful by allowing them to manage the state and handle side e
3 min read
How to Memoize with React.useMemo() ?
React provides a powerful tool for optimizing performance, the useMemo() hook. In this article, we'll delve into how useMemo() works, its benefits, and practical examples of how to manipulate it effectively in your React applications. Table of Content Understanding useMemo() Hook in ReactBenefits of
7 min read