React.memo ()
Tags: react, html, javascript, webdev
Published: 2022-01-12 14:29:50

`React.memo()` is one of those things that should be part of every React developer's arsenal. It gives us the ability to remember the React component. As with any tool, before we dive into how to use  `React.memo()`, let's first deal with the problem.

**Why do you need memoization?**
Memoization is a general concept that basically means caching the results of some computation for later use. This is an optimization technique that is quite widely used in the programming world.

It is important to remember that whenever memoization is used, there must be a criterion that will determine when the cached results are no longer valid and the computation must be performed again.

To understand the problem it solves, consider the following React component:

```js
import { useState, Fragment } from "react";

function App() {
  const [count, setCount] = useState(0);

  function handleDecrement() {
    setCount((oldCount) => --oldCount);
  }

  function handleIncrement() {
    setCount((oldCount) => ++oldCount);
  }

  return (
    <Fragment>
      <p>Count is {count}</p>
      <button onClick={handleDecrement}>-</button>
      <button onClick={handleIncrement}>+</button>
    </Fragment>
  );
}

export default App;
```
A simple component that keeps track of which can be increased or decreased.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1oe6l8rs16r9jxo2qy2.gif)
Now let's add another component to  `<App />`. To make things easier, we will create a component `<Message />`that returns some kind of message depending on the ID msgIdpassed to it as props.

```js
function Message(props) {
  let msg = "hello, world";

  if (props.msgId === 1) {
    msg = "hey there!";
  } else if (props.msgId === 2) {
    msg = "hola!";
  }

  return <p>{msg}</p>;
}
```
We've kept it simple here, but imagine this component  `<Message />` doing some heavy computation, or perhaps sending a request to an external API to get the final message. We will simulate this situation by adding  `console.log()` all the favorites to the mix.

```js
function Message(props) {
  let msg = "hello, world";

  console.log("Just performed some seriously heavy computation");

  if (props.msgId === 1) {
    msg = "hey there!";
  } else if (props.msgId === 2) {
    msg = "hola!";
  }

  return <p>{msg}</p>;
}
```
Let's update the component  `<App />` to use  `<Message />`.

```js
import { useState, Fragment } from "react";

function Message(props) {
  let msg = "hello, world";

  console.log("Just performed some seriously heavy computation");

  if (props.msgId === 1) {
    msg = "hey there!";
  } else if (props.msgId === 2) {
    msg = "hola!";
  }

  return <p>{msg}</p>;
}

function App() {
  const [count, setCount] = useState(0);

  function handleDecrement() {
    setCount((oldCount) => --oldCount);
  }

  function handleIncrement() {
    setCount((oldCount) => ++oldCount);
  }

  return (
    <Fragment>
      <Message msgId={1} />
      <p>Count is {count}</p>
      <button onClick={handleDecrement}>-</button>
      <button onClick={handleIncrement}>+</button>
    </Fragment>
  );
}

export default App;

```
In the video below, pay particular attention to the fact that with every change  count , heavy calculations are performed.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fiy4wggi5iab1k8djb0s.png)

At this point, take a step back and consider how ineffective our user interface is at the moment. `count` does not affect in any way  `<Message />`, but still `count` very heavy computation is performed every time you update  . We only want the computation to happen on change  `msgId`, because the change  `msgId` should result in a different message. 

**React.memo () rushes to the rescue**
`React.memo()` higher order component. It takes a component as an argument and remembers the result. The memoized result is updated only if the properties of the original component change.

To use  `React.memo()`, just pass your component as an argument and store the result. Our component  `<Message />` will be:

```js
import { useState, Fragment, memo } from "react";

const Message = memo(function (props) {
  let msg = "hello, world";

  console.log("Just performed some seriously heavy computation");

  if (props.msgId === 1) {
    msg = "hey there!";
  } else if (props.msgId === 2) {
    msg = "hola!";
  }

  return <p>{msg}</p>;
});
```
Note: I just imported here  `memo()`. If you imported  `React`, you can use `React.memo()` simply  `instead  memo()`.

Our code now looks like this:

```js
import { useState, Fragment, memo } from "react";

const Message = memo(function (props) {
  let msg = "hello, world";

  console.log("Just performed some seriously heavy computation");

  if (props.msgId === 1) {
    msg = "hey there!";
  } else if (props.msgId === 2) {
    msg = "hola!";
  }

  return <p>{msg}</p>;
});

function App() {
  const [count, setCount] = useState(0);

  function handleDecrement() {
    setCount((oldCount) => --oldCount);
  }

  function handleIncrement() {
    setCount((oldCount) => ++oldCount);
  }

  return (
    <Fragment>
      <Message msgId={1} />
      <p>Count is {count}</p>
      <button onClick={handleDecrement}>-</button>
      <button onClick={handleIncrement}>+</button>
    </Fragment>
  );
}

export default App;
```
Notice this time that the computation is done when the application is updated, but the change  `count `no longer has this effect.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyoyu9wifuyly56djuf0.png)