ReactuseMemo
Hookはメモ化された値を返します。
メモ化は、再計算する必要がないように値をキャッシュすることと考えてください。
フックuseMemo
は、依存関係の1つが更新された場合にのみ実行されます。
これにより、パフォーマンスが向上します。
のuseMemo
そしてuseCallback
フックは似ていますが、主な違いは次のとおりです。useMemo
メモ化された値を返し、useCallback
メモ化された関数を返します。詳細については、こちらをご覧ください。useCallback
の中にuseCallback の章。
パフォーマンス
フックuseMemo
を使用すると、高価でリソースを大量に消費する機能が不必要に実行されないようにすることができます。
この例では、すべてのレンダリングで実行される高価な関数があります。
カウントを変更したり、todoを追加したりすると、実行の遅延に気付くでしょう。
例:
独自のReact.jsサーバーを取得する。パフォーマンスの悪い機能。このexpensiveCalculation
関数はレンダリングごとに実行されます。
import { useState } from "react";
import ReactDOM from "react-dom/client";
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;
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
実行例(開発準備中)»
useMemo
を使用する
このパフォーマンスの問題を修正するには、useMemo
フックを使用してexpensiveCalculation
関数をメモ化します。これにより、関数は必要な場合にのみ実行されます。
高価な関数呼び出しをuseMemo
でラップできます。
フックuseMemo
は、依存関係を宣言するための 2番目のパラメーターを受け入れます。高価な関数は、その依存関係が変更された場合にのみ実行されます。
次の例では、高価な関数は次の場合にのみ実行されます。count
todoが追加されたときではなく、変更されます。
例:
フックを使用したパフォーマンス例useMemo
:
import { useState, useMemo } from "react";
import ReactDOM from "react-dom/client";
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;
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
実行例(開発準備中)»