REACT HOOKS - useMemo()
Tags: react, javascript, beginners
Published: 2022-08-23 12:37:00

**What is useMemo hook**

useMemo() hooks is used to prevent expensive calculation on every render by using memoization. 

useMemo() returns a memoized value only when its dependencies changes.

**What is Memoization**

Memoization is an optimization technique. It is used to speed up the computer program/component performance by storing the result of expensive operation and using the stored value if there is no change in the result.

If there is no change in the result of expensive function then it will not be recalculated but the stored value(cached value) will be used. 

**Optimizing the component using useMemo() hook**

let's see an example of how to use useMemo hook and when to use it.

First we need to create a react app. We can do so by using the below command
```npx create-react-app myApp```

Next I have create a function named ExpensiveCalculation in a js file of same name.
```javascript
function ExpensiveCalculation(num) {
    console.log("calculating...");
    for (let i = 0; i < 1000000000; i++) {
      num += 1;
    }
    return num;
}

export default ExpensiveCalculation;

```
the above function is the expensive function which decreases the performance of the component. The above function will add 1 to the `num` which is passed as a parameter in ExpensiveCalculation.

The for loop checks if the value of `i` is less than 1000000000, if this is true, 1 will be added to the previous value of `num` and then function will return the updated `num` value.

Then I have created a component named AddItems.js in src folder. Let's see how is the performance of the component without useMemo. 

```react
import { useState} from "react";

function AddItems() {
    const [items, setItems] = useState([]);
    const [count, setCount] = useState(1);

    // without memoization --> expensive calculation
    const calculation = ExpensiveCalculation(count)

    const addItems = () => {
        setItems((prev) => [...prev, `New item`]);
    };

    const incrementCount = () => {
        setCount((c) => c + 1);
    };

    return (
        <div>
            {items.map((item) => (
                <li>{item}</li>
            ))}
            <button onClick={addItems}>Add items</button>
            <div style={{ display: "flex" }}>
                <h2>Expensive Calculation</h2>
                <button onClick={incrementCount}>calculate</button>
                {calculation}
            </div>
        </div>
    );
}

export default AddItems;
```

ExpensiveCalculation is assigned to const calculation. No memoization is used here.

There is a button `Add Item` which add new items and it will be displayed in the browser.

There is another button `calculate` which will increment the `count` 

Now whenever we click on button `calculate` the count will increment and count is passed as argument in ExpensiveCalculation.

` const calculation = ExpensiveCalculation(count)`

In the file ExpensiveCalculation for loop will run and will check if i is less than 1000000000. This will take sometime because 1000000000 is a big value so AddItem will take time to re-render the updated value. 

Now when we click on `Add Item` button, ExpensiveCalcution will run as well and AddItem component will take longer to re-render even though we just wanted to add new item and display it.

![Without useMemo hook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5oi9vtnxmujh0bj0xrty.gif)
 

Because of ExpensiveCalculation, There is a delay in execution and AddItem component is taking longer to re-render. To fix this performance issue we will use useMemo hook.

To use memoization in react we have to import useMemo hook from react



```react
const calculation = useMemo(()=>ExpensiveCalculation(count),[count])
```

useMemo hook accepts a second parameter to declare dependencies. in the above code ExpensiveCalculation function will be called only when there is change in count.

![with useMemo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qwih7wid3lti98qshgl9.gif)

We can see that when count value is not changed then function returns the cached value and there is no lag when we click on add item button.
 
Below is the complete code after using useMemo hook.

```react
import { useState, useMemo } from "react";
import ExpensiveCalculation from "./ExpensiveCalculation";

function AddItems() {
    const [items, setItems] = useState([]);
    const [count, setCount] = useState(1);

    //with useMemo hook
    const calculation = useMemo(() => ExpensiveCalculation(count), [count])

    const addItems = () => {
        setItems((prev) => [...prev, `New item`]);
    };

    const incrementCount = () => {
        setCount((c) => c + 1);
    };

    return (
        <div style={{ display: "flex", displayDirection: "row", gap: "5rem" }}>
            <div>
                {items.map((item, idx) => (
                    <li key={idx}>{item}</li>
                ))}
                <button onClick={addItems}>Add items</button>
            </div>
            <div>
                <h2>Expensive Calculation</h2>
                <button onClick={incrementCount}>calculate</button>
                {calculation}
            </div>
        </div>
    );
}

export default AddItems;
```
React forget some previously memoized values and recalculate them on next render to free memory. Write your code so that it still works without useMemo — and then add it to optimize performance.