React メモ
memo
を使用すると、プロパティが変更されていない場合、Reactはコンポーネントのレンダリングをスキップします。
これにより、パフォーマンスが向上します。
このセクションではReact Hooksを使用します。React フックを参照してください。フックの詳細については、セクションを参照してください。
問題
この例では、todosが変更されていない場合でも、Todos
コンポーネントが再レンダリングされます。
例:
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;
インクリメントボタンをクリックすると、Todos
コンポーネントが再レンダリングされます。
このコンポーネントが複雑な場合、パフォーマンスの問題が発生する可能性があります。
解決策
これを解決するには、memo
を使用します。
memo
を使用してTodos
コンポーネントが不必要に再レンダリングしないようにします。
Todos
コンポーネントのエクスポートをmemo
でラップします。:
例:
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);
Todos
コンポーネントは、todos
props を介して渡されるものは更新されます。
これでTodos
コンポーネントは、props を通じて渡されたtodosが更新された場合にのみ再レンダリングされるようになりました。
プログラミング学習を加速させる
プログラミングをプロの講師に教えてもらいませんか。