How to: Increase performance with React.memo
Tags: tutorial, react, webdev
Published: 2020-09-17 10:51:35

In React, changes to a component's state triggers a re-render of the entire component tree. This means that not only does the render function of the component get called, all its subsequent child-components will re-render as well, even when their props have not changed.

When your application is large, unnecessary re-rendering is expensive and reduces performance. To avoid this, we can look at to a concept called Memoization.

## Memoization
Wikipedia defines Memoization to be:

> ... an optimisation technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.

This means that it is a technique that executes a **pure function** once, stores the results, and if the function is called again with the **same arguments**, it returns the previously saved results without executing the function again (because we assume the outcome is the same). 

In other words, it is a away to lower the function's time cost in exchange for space cost; that is, memoized functions become optimised for speed in exchange for a higher use of computer memory space.

## React.memo in action
In the context of React, the functions are our React (pure) components, and the arguments are our props. `React.memo` is a HOC built of the concept of memoization and tells the component to only re-render when its props change.

Let's create a component that has an input field and a button to add a new user: 

```jsx
const App = () => {
  const [value, setValue] = useState("");
  const [names, setNames] = useState(["Avery", "Bain"]);

  const handleInput = (e) => {
    setValue(e.target.value)
  }

  const handleAddUser = () => {
    const updatedArray = names.push(value);
    setNames(updatedArray);
  }

  console.log('render App');
  return (
    <div>
        <input value={value} onChange={handleInput} />
        <button onClick={handleAddUser}>
          Add User
        </button>
        <List list={names} />
    </div>
  )
};

const List = ({list}) => {
  console.log('render List');
  return (
    <ul>
      {list.map((name, key) => <li>{name}</li>)};
    </ul>
  )
};

export default App;
```

In here, the component gets re-rendered every time someone types into the input field (before adding a user), because `value` changes.  The problem is, `List` also gets re-rendered, even when its props remains the same.

```jsx
// when user types one char into input
render App
render List
```

With `React.memo`, we can optimise rendering behaviour by telling List to only re-render when its props changes:

```jsx
import { memo } from 'React';

const List = memo(({list}) => {
    console.log('render List');
    return (
        <ul>
          {list.map((name, key) => <li>{name}</li>)};
        </ul>
    )
});
```

Now, when we type into the input field, only `App` is re-rendered because it is the only component affected by the state change.

```jsx
// when user types one char into input
render App

// when a new user is added
render App
render List
```

## To recap

By default, React re-renders components when its state changes. This means that a child component will also render as a result of a state change in its parent component, even when its props remain the same.

React's memo API optimises rendering behaviour by re-rendering components only when their props change. Thoughts? Let me know in the comments below! 👇

## References

[https://www.robinwieruch.de/react-memo](https://www.robinwieruch.de/react-memo)