ReactuseMemo
フック
React useMemo
Hookは、メモ化された値を返します。
メモ化は、値をキャッシュして、再計算する必要がないようにすることと考えてください。
useMemo
フックは、依存関係の1つが更新されたときにのみ実行されます。
これにより、パフォーマンスを向上させることができます。
とフックは似ていますuseMemo
。useCallback
主な違いは、メモ化されuseMemo
た値を
useCallback
返し、メモ化された関数を返すことです。詳細についてuseCallback
は、useCallbackの章をご覧ください。
パフォーマンス
useMemo
フックを使用すると、高価でリソースを大量に消費する機能が不必要に実行されないようにすることができます。
この例では、すべてのレンダリングで実行される高価な関数があります。
カウントを変更したり、ToDoを追加したりすると、実行が遅れることに気付くでしょう。
例:
パフォーマンスの悪い機能。expensiveCalculation
関数はすべてのレンダリングで実行されます。
import { useState } from "react";
import ReactDOM from "react-dom";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState([]);
const calculation = expensiveCalculation(count);
const increment = () => {
setCount((c) => c + 1);
};
const addTodo = () => {
setTodos((t) => [...t, "New Todo"]);
};
return (
<div>
<div>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
<button onClick={addTodo}>Add Todo</button>
</div>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
<h2>Expensive Calculation</h2>
{calculation}
</div>
</div>
);
};
const expensiveCalculation = (num) => {
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {
num += 1;
}
return num;
};
ReactDOM.render(<App />, document.getElementById('root'));
つかいますuseMemo
このパフォーマンスの問題を修正するために、useMemo
フックを使用してexpensiveCalculation
関数をメモ化できます。これにより、関数は必要な場合にのみ実行されます。
高価な関数呼び出しをでラップできますuseMemo
。
useMemo
フックは、依存関係を宣言するための2番目のパラメーターを受け入れます。高価な関数は、依存関係が変更された場合にのみ実行されます。
次の例では、高価な関数は変更された場合にのみ実行count
され、todoが追加された場合には実行されません。
例:
useMemo
フックを使用したパフォーマンスの例:
import { useState, useMemo } from "react";
import ReactDOM from "react-dom";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState([]);
const calculation = useMemo(() => expensiveCalculation(count), [count]);
const increment = () => {
setCount((c) => c + 1);
};
const addTodo = () => {
setTodos((t) => [...t, "New Todo"]);
};
return (
<div>
<div>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
<button onClick={addTodo}>Add Todo</button>
</div>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
<h2>Expensive Calculation</h2>
{calculation}
</div>
</div>
);
};
const expensiveCalculation = (num) => {
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {
num += 1;
}
return num;
};
ReactDOM.render(<App />, document.getElementById('root'));