React memo
Tags: react
Published: 2021-07-14 10:25:34

Hello Guys...

In this post I will explain how we can make use of React **memo** to improve the UI performance.

###Prerequisite

Before you dive into the article, it is important you understand what react hooks are. It is also important to understand how a HOC(Higher Order Component) works. If you are new to these concepts, I will suggest you to go through the official documentation. 
Here is the link to hooks ([hooks](https://reactjs.org/docs/hooks-intro.html)).

Here is the link to HOC ([HOC](https://reactjs.org/docs/higher-order-components.html)).

When we build an application, it is important we consider different ways of improving the performance because every second or even every millisecond matters for the user. 

Once of the ways to improve UI performance is by avoiding unnecessary rendering. Wrapping a component with **memo** helps us avoid unnecessary rendering. React **memo** basically gives a **memoized** version of the component. When I say avoid unnecessary rendering I mean not rendering a component when it's props have not changed. 

Let us see an example.

```javascript
  import MyComponent from './MyComponent';

  const MyApp = () => {
    const [incrementValue, setIncrementValue] = useState(0);
    const [decrementValue, setDecrementValue] = useState(0);
    
    const handleIncrement= () => {
      setIncrementValue(incrementValue + 1);
    }

    const handleDecrement = () => {
      setDecrementValue(decrementValue + 1);
    }
    return (
      <div>
        <button onClick={handleIncrement}>Increment</button>
        <button onClick={handleDecrement}>Decrement</button>
        // 1st MyComponent
        <MyComponent key='1' value={`Increment-${incrementValue}`} />
        // 2nd MyComponent
        <MyComponent key='2' value={`Decrement-${decrementValue}`} />
      </div>
    )
  }
  
  // MyComponent.js
  const MyComponent = ({ value }) => {
    console.log('I am being rendered', value);
    return (
      <p>Value is {value}</p>
    )
  }
  
  export default MyComponent;
```
Above I have a component MyApp which renders couple of buttons. The first button increases the incrementValue and the second one decreases the decrementValue. Also I have couple of MyComponent components.

Let's try to understand what MyComponent is doing here.

MyComponent takes a value prop and displays the value. I have added a console statement to clearly understand which component is getting rendered.

Now when I load MyApp component, you will see
```javascript
  I am being rendered Increment-0    //1st MyComponent
  I am being rendered Decrement-0    //2nd MyComponent
```
in the console because the App was rendered for the first time. Fair enough.

Now I click on Increment button. What do you this should be logged in the console.

```javascript
  I am being rendered Increment-1   //1st MyComponent
  I am being rendered Decrement-0   //2nd MyComponent
```

This means both the MyComponent were re-rendered. If you look closely at the 2nd MyComponent, the prop **value** did not change because nothing happened to decrementValue when we clicked the Increment button. It is still the same(0) but was re-rendered. So this is an unnecessary render. How do we avoid re-rendering of 2nd MyComponent?

Let's make a small change in the MyComponent.js

```javascript
  import { memo } from 'react;
  const MyComponent = ({ value }) => {
    console.log('I am being rendered', value);
    return (
      <p>Value is {value}</p>
    )
  }
  
  export default memo(MyComponent);
```
Now when we reload MyApp, for the initial rendering we will still see
```javascript
  I am being rendered Increment-0    //1st MyComponent
  I am being rendered Decrement-0    //2nd MyComponent
```
in the console.

Now I click the Increment button. What do you think will be logged to console!!!

```javascript
  I am being rendered Increment-1    //1st MyComponent
```
This means only 1st MyComponent was rerendered because its **value ** prop changed but for the 2nd MyComponent nothing changed, so it didn't re-render.

So we saw how React memo helps in avoiding unnecessary rendering thus improving the UI performance.

This is a very simple example where I demonstrated how react memo
helps us in avoiding unnecessary rendering. But we have to understand when should a component be wrapped with memo because memoizing something comes with a cost.

Usually,
  **1.** if a component is light weight and renders with different 
  props, you may not want to memoize it.
  **2.** if a component is heavy and it renders with same props, 
  you would like to memoize it. 

#####Note - This is a simple example where the component accepts a simple string prop. We can all also have a function as a prop and for a function prop we can memoize it with using useCallback hook to avoid unnecessary rendering.

##Conclusion
React **memo** is one of the ways to improve the UI performance. It might not that relevant when the application is small, but as the application grows, it becomes very important to check for different ways to improve the performance of the application.