Utilizing React.memo
helps optimize performance by skipping the re-rendering of a component if its props have not changed.
Performance Optimization
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
:
const TaskList = ({ tasks }) => { console.log("child render"); return ( <> <h2>Task List</h2> {tasks.map((task, idx) => ( <p key={idx}>{task}</p> ))} </> ); }; export default TaskList;
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.
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);