React Performance Booster - Introduction to the useMemo hook

rasaf_ibrahim

Rasaf Ibrahim

Posted on October 26, 2023

React Performance Booster - Introduction to the useMemo hook

Hooks have revolutionized the way developers build React applications, offering a more intuitive and functional approach to state and side effects. Among these hooks, useMemo stands out for optimizing performance by memorizing computed values. Let’s delve into this powerful hook, step by step.

 

📌 Table of Contents

 

What is the useMemo Hook?

 

useMemo is a hook introduced in React 16.8 that allows you to memorize expensive calculations, ensuring they don't get re-executed unless their dependencies change. This can help in optimizing performance, especially in heavy computational scenarios.

 

Why Do We Need useMemo?

 

Imagine a situation where a function re-renders frequently or performs hefty calculations every time a component updates. This can degrade the performance of the application. By using useMemo, you can ensure that the result of an expensive computation is stored and only recalculated if necessary.

 

Syntax of useMemo

 

The useMemo hook has a simple syntax:

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Enter fullscreen mode Exit fullscreen mode

Here, computeExpensiveValue is a hypothetical function. The function provided to useMemo will only recompute when a or b change.

 

Breaking Down the Syntax

 

  1. Callback function: The first argument to useMemo is a function that computes and returns a value.
  2. Dependency array: The second argument is an array of dependencies. The memorized value will only recompute when any value in this array changes.

 

Basic Example of useMemo

 

Imagine we have a list of books, and we want to filter them based on a user's search query.

Consider this basic example:

function App() {
    const [query, setQuery] = useState('');
    const [books, setBooks] = useState(['Harry Potter', 'Lord of the Rings', 'Hobbit', 'Percy Jackson']);

    const filteredBooks = books.filter(book => book.toLowerCase().includes(query.toLowerCase()));

    return (
        <div>
            <input 
                type="text" 
                value={query} 
                placeholder="Search for a book..."
                onChange={e => setQuery(e.target.value)} 
            />
            <ul>
                {filteredBooks.map(book => (
                    <li key={book}>{book}</li>
                ))}
            </ul>
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

In this example, every time the component re-renders, we're filtering the entire books list, even if the books or the query haven't changed.

By using useMemo, we can optimize the filtering:

function App() {
    const [query, setQuery] = useState('');
    const [books, setBooks] = useState(['Harry Potter', 'Lord of the Rings', 'Hobbit', 'Percy Jackson']);

    const filteredBooks = useMemo(() => 
        books.filter(book => book.toLowerCase().includes(query.toLowerCase())),
        [books, query]
    );

    return (
        <div>
            <input 
                type="text" 
                value={query} 
                placeholder="Search for a book..."
                onChange={e => setQuery(e.target.value)} 
            />
            <ul>
                {filteredBooks.map(book => (
                    <li key={book}>{book}</li>
                ))}
            </ul>
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

Now, the books are only filtered again if the books array or the query changes. This ensures that we're not doing unnecessary computations when other unrelated parts of the component update.

 

rich-text-editor-for-react npm package

Demo | Documentation

 

Common Mistakes with useMemo

 

  1. Overusing it: Not every value or function in a component needs to be memorized. Use useMemo only when necessary, as it can add unnecessary complexity and overhead.

  2. Forgetting dependencies: Always ensure that every value used inside the useMemo callback is listed in the dependency array. Omitting dependencies can lead to stale values and hard-to-debug issues.

 

When to Use useMemo?

 

  • When you deal with heavy computations.
  • When the same computation is repeated multiple times and returns the same result for the same inputs.
  • When rendering large lists or data grids and you want to avoid unnecessary re-renders.

 

useMemo vs useCallback

 

Both useMemo and useCallback serve to optimize performance, but they are used in slightly different scenarios:

  • useMemo returns a memorized value.
  • useCallback returns a memorized callback.

If you're looking to optimize a function (not its result) to avoid re-renders in child components or re-invocations, then useCallback is your go-to.

 

Wrapping Up

 

The useMemo hook is a powerful tool for optimizing React applications by memorizing expensive computations. By understanding its purpose, syntax, and best practices, developers can build efficient and responsive applications. Remember, while useMemo is beneficial, it should be used judiciously, only when necessary.

 

That's it. 😃 Thanks for reading. 🎉

💖 💪 🙅 🚩
rasaf_ibrahim
Rasaf Ibrahim

Posted on October 26, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related