bugl
bugl
HomeLearnPatternsPathsSearch
HomeLearnPatternsPathsSearch

Loading lesson path

Learn/React/Hooks and State Management
React•Hooks and State Management

React useMemo Hook

Flash cards

Review the key moves

1/4
Core idea

What is the main idea behind React useMemo Hook?

Lesson checks

Practice each idea before moving on

Short Mimo-style checks built from this lesson's code, terms, and sequence.

1Quick choice

Which statement best captures the main point of this lesson?

2Fill blank

Complete the missing token from the example code.

___ { useState } from 'react';
3Order

Put the learning moves in the order that makes the concept easiest to apply.

Think of memoization as caching a value so that it does not need to be recalculated.
The React useMemo Hook returns a memoized value.
React useMemo Hook

The React useMemo Hook returns a memoized value.

Think of memoization as caching a value so that it does not need to be recalculated.

The useMemo Hook only runs when one of its dependencies update.

This can improve performance.

The useMemo and useCallback Hooks are similar:

useMemo returns a memoized value.

useCallback returns a memoized function.

Learn more about useCallback in the useCallback chapter .

Without useMemo

The useMemo Hook can be used to keep expensive, resource intensive functions from needlessly running.

In this example, we have an expensive function that runs on every render.

When changing the count or adding a todo, you will notice a delay in execution.

Example

A poor performing function. The expensiveCalculation function runs on every render:

import { useState } from 'react';
import { createRoot } from 'react-dom/client';
const App = () => {
 const [count, setCount] = useState(0);
 const [todos, setTodos] = useState([]);
 const calculation = expensiveCalculation(count);
 const increment = () => {
 setCount((c) => c + 1);
 };
 const addTodo = () => {
 setTodos((t) => [...t, "New Todo"]);
 };
 return ( <div> <div> <h2>My Todos</h2> {todos.map((todo, index) => {
 return <p key={index}>{todo}</p>;
 })}
 <button onClick={addTodo}>Add Todo</button> </div> <hr /> <div> Count: {count}
 <button onClick={increment}>+</button> <h2>Expensive Calculation</h2> {calculation}
 <p>Note that this example executes the expensive function also when you click on the Add Todo button.</p> </div> </div> );
 };
 const expensiveCalculation = (num) => {
 console.log("Calculating...");
 for (let i = 0; i < 1000000000; i++) {
 num += 1;
 }
 return num;
 };
 createRoot(document.getElementById('root')).render( <App /> );

Use useMemo

To fix this performance issue, we can use the useMemo Hook to memoize the expensiveCalculation function. This will cause the function to only run when needed.

We can wrap the expensive function call with useMemo .

The useMemo Hook accepts a second parameter to declare dependencies. The expensive function will only run when its dependencies have changed.

In the following example, the expensive function will only run when count is changed and not when todo's are added.

Performance example using the useMemo Hook

import { useState, useMemo } from 'react';
import { createRoot } from 'react-dom/client';
const App = () => {
 const [count, setCount] = useState(0);
 const [todos, setTodos] = useState([]);
 const calculation = useMemo(() => expensiveCalculation(count), [count]);
 const increment = () => {
 setCount((c) => c + 1);
 };
 const addTodo = () => {
 setTodos((t) => [...t, "New Todo"]);
 };
 return ( <div> <div> <h2>My Todos</h2> {todos.map((todo, index) => {
 return <p key={index}>{todo}</p>;
 })}
 <button onClick={addTodo}>Add Todo</button> </div> <hr /> <div> Count: {count}
 <button onClick={increment}>+</button> <h2>Expensive Calculation</h2> {calculation}
 </div> </div> );
 };
 const expensiveCalculation = (num) => {
 console.log("Calculating...");
 for (let i = 0; i < 1000000000; i++) {
 num += 1;
 }
 return num;
 };
 createRoot(document.getElementById('root')).render( <App /> );

Previous

React useCallback Hook

Next

React Custom Hooks