When to use memo in React
Tags: react, javascript, beginners, frontend
Published: 2023-06-02 15:59:36

**Let's first understand how React re-renders**

***State change***:
When a state change it re-render its component, it also re-render all of its descendants components. 
Let's understand by an example

```js
export default function App() {
  return (
    <div className="app">
      <Counter />
    </div>
  );
}

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleCount = () => {
    setCount(count + 1);
  };

  return (
    <div className="counter">
      <Display count={count} />
      <button onClick={handleCount}>Count</button>
    </div>
  );
};

const Display = ({ count }) => {
  return <div>{count}</div>;
};

```

So I'm not going to bore you to read every lines of the code. Here are highlights:

- The main component is `<App />` which renders `<Counter />` and which renders `<Display />`, The `Counter` has `count` state and a button which triggers `handleCount` on click.

Whenever the `count` state change, the `Counter` component will re-render and it re-renders all of its descendents component. 

**_But why `App` component didn't re-render?_** 
The answer is very simple the `count` state is defined inside the `Counter` component and we are updating the `count` state, so it will re-render that component and its descendants.

After understanding how component re-renders in React, let's take a look at **when to use memo() in React.**

```js
export default function App() {
  const [list] = useState(USERS); // List of users
  const [color, setColor] = useState("#fdd3c2");

  const handleColor = () => {
    const randomColor = getRandomColor();
    setColor(randomColor);
  };

  return (
    <div style={{ backgroundColor: color }} className="App">
      <List list={list} />
      <Button handleColor={handleColor} color={color} />
    </div>
  );
}

const Button = ({ color, handleColor }) => {
  return (
    <button className="button" onClick={handleColor}>
      {color}
    </button>
  );
};

const List = ({ list }) => {
  return (
    <ul>
      {list.map((item) => {
        return <li key={item.id}>{item.name}</li>;
      })}
    </ul>
  );
};

```

Here are highlights:

1. We have two state named _list_ and _color_ in `App` component. The `App` component renders two components `List` and `Button`
2. The list state is passing to `List` component through prop and render the list inside `List` component.
3. The _color_ state is passing to `Button` component through prop.

so when the user clicks on button the _color_ state is changed, because of _color_ state defined inside `App` component. The `App`component re-render and it also re-render both `List` and `Button` component but here is the problem, why we want to re-render List component even though _list_ state hasn't changed and also we are not passing _color_ as a prop to <List> right. It might be a performance problem if the list is too long.

We can wrap the whole List component inside memo() to avoid unneccesary re-render of component if the prop hasn't changed

```js
...
const List = memo(({ list }) => {
  console.log("Re-render List")
  return (
    <ul>
      {list.map((item) => {
        return <li key={item.id}>{item.name}</li>;
      })}
    </ul>
  );
});
```
Now, If we clicks on button to change the color, the `<List>` will not re-render because the _list_ props has not changed and we wrapped the `<List>` component inside memo().

**What does the mean of memo?**
Memo means memoization (memorization), it is a cache technique in which react will re-use the previous snapshot if the none of props have changed rather than going to generating a brand new.

By this technique we can save unwanted re-renders of component if the props have not changed.

***NOTE:***

- **This is technique will not useful in most of scenerios, we must not have to wrap all of components inside memo()**
- **This technique will not works on if the props are objects or function because objects or functions are recreate everytime on re-render. To use memo() techniques on objects and functions we can wrap objects and functions inside useMemo() and useCallback respectively**

[Codepen Link](https://codesandbox.io/s/flamboyant-panka-goed4t?file=/src/App.js)