[React.js] - パート15: React Hooks - useMemo Hook

Ace Lennox
ReactのuseMemo
フックは、計算結果をメモ化することでパフォーマンスを最適化します。メモ化とは、計算結果をキャッシュし、依存関係が変更されない限り再計算を避ける仕組みです。このガイドでは、useMemo
フックの使い方をシンプルな例を使って詳しく解説します。
useMemo
とは?
useMemo
フックは、計算コストの高い関数の結果をメモ化して、再レンダリング時の無駄な再計算を防ぐために使用します。
useMemo
の主な特徴:
パフォーマンス最適化: 高コストな計算処理を防ぎます。
依存関係: 指定した依存関係が変更された場合にのみ再計算されます。
useCallback
との違い:useMemo
はメモ化された値を返し、useCallback
はメモ化された関数を返します。
問題:計算コストが高い関数
計算コストが高い関数が毎回レンダリングで実行されるアプリを考えてみましょう。
例:useMemo
なし
import { useState } from "react";
import ReactDOM from "react-dom/client";
const App = () => {
const [count, setCount] = useState(0);
const [tasks, setTasks] = useState([]);
const heavyComputation = (num) => {
console.log("重い計算を実行中...");
let result = 0;
for (let i = 0; i < 1000000000; i++) {
result += num;
}
return result;
};
const result = heavyComputation(count);
const increment = () => setCount((c) => c + 1);
const addTask = () => setTasks((prev) => [...prev, `タスク ${prev.length + 1}`]);
return (
<div>
<h2>タスク</h2>
{tasks.map((task, index) => (
<p key={index}>{task}</p>
))}
<button onClick={addTask}>タスクを追加</button>
<hr />
<h2>カウント: {count}</h2>
<button onClick={increment}>カウントを増やす</button>
<h3>計算結果: {result}</h3>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
問題: パフォーマンスが悪い
カウントを増やしたりタスクを追加するたびにheavyComputation
が実行され、処理に遅延が発生します。
解決策:useMemo
の使用
useMemo
を使うことで、計算処理をメモ化し、必要な場合にのみ再計算するようにできます。
例:useMemo
を使った最適化
import { useState, useMemo } from "react";
import ReactDOM from "react-dom/client";
const App = () => {
const [count, setCount] = useState(0);
const [tasks, setTasks] = useState([]);
const heavyComputation = (num) => {
console.log("重い計算を実行中...");
let result = 0;
for (let i = 0; i < 1000000000; i++) {
result += num;
}
return result;
};
const result = useMemo(() => heavyComputation(count), [count]);
const increment = () => setCount((c) => c + 1);
const addTask = () => setTasks((prev) => [...prev, `タスク ${prev.length + 1}`]);
return (
<div>
<h2>タスク</h2>
{tasks.map((task, index) => (
<p key={index}>{task}</p>
))}
<button onClick={addTask}>タスクを追加</button>
<hr />
<h2>カウント: {count}</h2>
<button onClick={increment}>カウントを増やす</button>
<h3>計算結果: {result}</h3>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
なぜこれが効果的なのか?
useMemo
がheavyComputation
の結果をメモ化します。依存関係
count
が変更された場合にのみ再計算されるため、タスク追加時の無駄な計算が防止されます。
useMemo
を使うべき場面
計算コストが高い関数: 実行時間が長い関数の最適化に適しています。
頻繁な再レンダリング: 再レンダリングが多い場合に不要な再計算を防ぎます。
複雑な計算: 状態やプロパティから派生した値を計算する場合にキャッシュを利用します。
ベストプラクティス
必要な場合にのみ使用:
useMemo
を乱用せず、パフォーマンスが重要な場面に限定して使用します。依存関係を正確に設定: メモ化する関数で使用するすべての変数を依存配列に含めます。
デバッグの活用:
console.log
を使って関数が実際に再実行されているか確認しましょう。
まとめ
useMemo
フックは、Reactアプリケーションのパフォーマンスを最適化するための重要なツールです。計算結果をメモ化することで、パフォーマンスの低下を防ぎ、スムーズなユーザー体験を提供できます。
この記事の例を参考に、useMemo
を活用して効率的なReactアプリケーションを構築してみましょう!
ソースコード
このプロジェクトの完全なソースコードはGitHubで利用可能です。