React Performance Booster - Introduction to the useMemo hook
Tags: react, usememo, hook, webdev
Published: 2023-10-26 20:02:55


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.


&nbsp;

**📌 Table of Contents**

- [What is the useMemo Hook?](#what-is-the-usememo-hook)
- [Why Do We Need useMemo?](#why-do-we-need-usememo)
- [Syntax of useMemo](#syntax-of-usememo)
- [Basic Example of useMemo](#basic-example-of-usememo)
- [Common Mistakes with useMemo](#common-mistakes-with-usememo)
- [When to Use useMemo?](#when-to-use-usememo)
- [useMemo vs useCallback](#usememo-vs-usecallback)
- [Wrapping Up](#wrapping-up)


&nbsp;

### What is the useMemo Hook?

&nbsp;

`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.

&nbsp;

### Why Do We Need useMemo?

&nbsp;

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.


&nbsp;

### Syntax of useMemo

&nbsp;

The `useMemo` hook has a simple syntax:

```javascript
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
```

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


&nbsp;

**Breaking Down the Syntax**

&nbsp;

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.

&nbsp;

### Basic Example of useMemo

&nbsp;

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

Consider this basic example:

```javascript
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>
    );
}
```

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:

```javascript
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>
    );
}
```

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.

&nbsp;



![rich-text-editor-for-react npm package](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scz09ynfwbdvqflj9ssh.png)
>[Demo](https://rich-text-editor-for-react.rasaf-ibrahim.com) | [Documentation](https://docs.rich-text-editor-for-react.rasaf-ibrahim.com)



&nbsp;

### Common Mistakes with useMemo

&nbsp;

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.

&nbsp;

### When to Use useMemo?

&nbsp;

- 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.

&nbsp;

### useMemo vs useCallback

&nbsp;

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.


&nbsp;

### Wrapping Up

&nbsp;

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.

&nbsp;

That's it. 😃 Thanks for reading. 🎉