DEV Community

Abdulrahman Gaoba
Abdulrahman Gaoba

Posted on • Edited on

2 2

React.memo ()

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:

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;
Enter fullscreen mode Exit fullscreen mode

A simple component that keeps track of which can be increased or decreased.

Image description

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.

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>;
}
Enter fullscreen mode Exit fullscreen mode

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.

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>;
}
Enter fullscreen mode Exit fullscreen mode

Let's update the component <App /> to use <Message />.

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;

Enter fullscreen mode Exit fullscreen mode

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

Image description

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:

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>;
});
Enter fullscreen mode Exit fullscreen mode

Note: I just imported here memo(). If you imported React, you can use React.memo() simply instead memo().

Our code now looks like this:

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;
Enter fullscreen mode Exit fullscreen mode

Notice this time that the computation is done when the application is updated, but the change countno longer has this effect.

Image description

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

While many AI coding tools operate as simple command-response systems, Qodo Gen 1.0 represents the next generation: autonomous, multi-step problem-solving agents that work alongside you.

Read full post

Top comments (0)

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

Best practices for optimal infrastructure performance with Magento

Running a Magento store? Struggling with performance bottlenecks? Join us and get actionable insights and real-world strategies to keep your store fast and reliable.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️