Using memo
allows React to skip rendering a component if its props haven’t changed, which can enhance performance.
This section utilizes React Hooks. For additional details on Hooks, refer to the React Hooks section. |
Problem
In this example, the Todos component re-renders even if the todos have not changed.
Example:
index.js:
import { useState } from "react";
import ReactDOM from "react-dom/client";
import Todos from "./Todos";
const App = () => {
const [count , setCount ] = useState(0);
const [todos , setTodos ] = useState(["todo 1", "todo 2"]);
const increment = () => {
setCount((c) => c + 1);
};
return (
<> <Todos todos={todos} /> <hr /> <div> Count: {count } <button onClick={increment}>+</button> </div> </>
); };
const root = ReactDOM .createRoot(document .getElementById('root'));
root .render(<App />);
|
Todos.js:
const Todos = ({ todos }) => {
console .log("child render");
return (
<> <h2>My Todos</h2> {todos .map((todo, index) => {
return <p key={index}>{todo }</p>;
})} </>
); };
export default Todos ;
|
Clicking the increment button causes the Todos component to re-render. If the component were more complex, this could lead to performance issues.
Solution
To address this, we can use memo to prevent the Todos component from unnecessary re-renders.
Wrap the export of the Todos component in memo as follows:
Example:
index.js:
import { useState } from "react";
import ReactDOM from "react-dom/client";
import Todos from "./Todos";
const App = () => {
const [count , setCount ] = useState(0);
const [todos , setTodos ] = useState(["todo 1", "todo 2"]);
const increment = () => {
setCount((c) => c + 1);
};
return (
<> <Todos todos={todos} /> <hr /> <div> Count: {count } <button onClick={increment}>+</button> </div> </>
); };
const root = ReactDOM .createRoot(document .getElementById('root'));
root .render(<App />);
|
Todos.js:
import { memo } from "react";
const Todos = ({ todos }) => {
console .log("child render");
return (
<> <h2>My Todos</h2> {todos .map((todo, index) => {
return <p key={index}>{todo }</p>;
})} </>
);
};
export default memo(Todos );
|
Now, the Todos component will only re-render when the todos passed to it via props are updated.