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

Ace Lennox
2025年01月19日読了時間:3分

ReactのuseMemoフックは、計算結果をメモ化することでパフォーマンスを最適化します。メモ化とは、計算結果をキャッシュし、依存関係が変更されない限り再計算を避ける仕組みです。このガイドでは、useMemoフックの使い方をシンプルな例を使って詳しく解説します。


useMemoとは?

useMemoフックは、計算コストの高い関数の結果をメモ化して、再レンダリング時の無駄な再計算を防ぐために使用します。

useMemoの主な特徴:

  1. パフォーマンス最適化: 高コストな計算処理を防ぎます。

  2. 依存関係: 指定した依存関係が変更された場合にのみ再計算されます。

  3. 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 />);

なぜこれが効果的なのか?

  • useMemoheavyComputationの結果をメモ化します。

  • 依存関係countが変更された場合にのみ再計算されるため、タスク追加時の無駄な計算が防止されます。


useMemoを使うべき場面

  1. 計算コストが高い関数: 実行時間が長い関数の最適化に適しています。

  2. 頻繁な再レンダリング: 再レンダリングが多い場合に不要な再計算を防ぎます。

  3. 複雑な計算: 状態やプロパティから派生した値を計算する場合にキャッシュを利用します。


ベストプラクティス

  1. 必要な場合にのみ使用: useMemoを乱用せず、パフォーマンスが重要な場面に限定して使用します。

  2. 依存関係を正確に設定: メモ化する関数で使用するすべての変数を依存配列に含めます。

  3. デバッグの活用: console.logを使って関数が実際に再実行されているか確認しましょう。


まとめ

useMemoフックは、Reactアプリケーションのパフォーマンスを最適化するための重要なツールです。計算結果をメモ化することで、パフォーマンスの低下を防ぎ、スムーズなユーザー体験を提供できます。

この記事の例を参考に、useMemoを活用して効率的なReactアプリケーションを構築してみましょう!


ソースコード

このプロジェクトの完全なソースコードはGitHubで利用可能です。


最近の投稿

Latest Posts


logo

プログラミング、ウェブ開発、モバイルアプリ作成に関する洞察的な記事とチュートリアルを探索します。ReactJS、Next.js、Android、iOS、および最新のコーディングプラクティスについて学びます。実践的な例と、アプリケーションを構築するためのヒントを学びます。すべてのレベルの開発者がスキルを向上させるための理想的な場所です。

SNS

© 2025. All rights reserved