React Memo

Utilizing React.memo helps optimize performance by skipping the re-rendering of a component if its props have not changed.

Tutorials dojo strip

By avoiding unnecessary re-renders, React.memo can boost your application’s performance.

Problem

Consider this example where the TaskList component re-renders even if the tasks haven’t changed.

index.js:

import { useState } from "react";
import ReactDOM from "react-dom/client";
import TaskList from "./TaskList";

const App = () => {
  const [counter, setCounter] = useState(0);
  const [tasks, setTasks] = useState(["task 1", "task 2"]);

  const incrementCounter = () => {
    setCounter((prevCounter) => prevCounter + 1);
  };

  return (
    <>
      <TaskList tasks={tasks} />
      <hr />
      <div>
        Counter: {counter}
        <button onClick={incrementCounter}>+</button>
      </div>
    </>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

TaskList.js:

In this setup, clicking the increment button triggers a re-render of the TaskList component, even though the tasks haven’t changed. If this component were more complex, it could negatively affect performance.

const TaskList = ({ tasks }) => {
  console.log("child render");
  return (
    <>
      <h2>Task List</h2>
      {tasks.map((task, idx) => (
        <p key={idx}>{task}</p>
      ))}
    </>
  );
};

export default TaskList;

Solution

To resolve this issue, we can use React.memo. Wrapping the TaskList component in React.memo prevents unnecessary re-renders.

index.js

import { useState } from "react";
import ReactDOM from "react-dom/client";
import TaskList from "./TaskList";

const App = () => {
  const [counter, setCounter] = useState(0);
  const [tasks, setTasks] = useState(["task 1", "task 2"]);

  const incrementCounter = () => {
    setCounter((prevCounter) => prevCounter + 1);
  };

  return (
    <>
      <TaskList tasks={tasks} />
      <hr />
      <div>
        Counter: {counter}
        <button onClick={incrementCounter}>+</button>
      </div>
    </>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

TaskList.js:

import { memo } from "react";

const TaskList = ({ tasks }) => {
  console.log("child render");
  return (
    <>
      <h2>Task List</h2>
      {tasks.map((task, idx) => (
        <p key={idx}>{task}</p>
      ))}
    </>
  );
};

export default memo(TaskList);
Tutorials dojo strip
Tutorials dojo strip
Scroll to Top