Utilizing React.memo
helps optimize performance by skipping the re-rendering of a component if its props have not changed.
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);