1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🚀 ReactのuseMemo入門|パフォーマンス最適化の第一歩

Posted at

📝 はじめに

Reactでは、再レンダーのたびにコンポーネントが再実行されるため、
重い処理や配列の再計算があると、パフォーマンスに影響することがあります。

そんなときに活躍するのが useMemo フック です。
今回は、useMemoの基本的な使い方から、実際のサンプルコードまで解説します。

⚙️ 前提条件

この記事では以下の知識を前提としています。

  • Reactの基本文法(useState, useEffect)

  • JavaScriptの基本的な関数や配列操作の理解

🎯 今回の目標

  • useMemoの役割を理解する

  • 再レンダー時の無駄な再計算を防ぐ方法を学ぶ

  • 実際のコードで動作を確認する

💡 useMemoとは?

useMemo は、 「値をメモ化(記憶)して再利用する」 ためのReactフックです。
特に以下のようなケースで使用します👇

  • 計算コストの高い処理を毎回実行したくない

  • 同じ入力値で同じ結果を再計算するのを避けたい

🔹基本構文

const memoizedValue = useMemo(() => {
  return heavyCalculation(value1);
}, [value2]);

第一引数(value1):計算関数。ここで実際に重い処理などを実行します。

第二引数(value2):依存配列。この値が変わったときだけ再計算されます。

※ 実際のコードでは、value1 と value2 が同じ変数(例:count)になることも多いです。
ここでは「計算に使う値」と「再計算をトリガーする値」を分かりやすく分けて記載しています。

🧩 サンプルコード:重い計算を最適化してみよう

✨ App.jsx
App.jsx
import React, { useState, useMemo } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState("");

  // 🔥 計算コストの高い関数(例:大きなループ)
  const heavyCalculation = (num) => {
    console.log("重い計算を実行中...");
    let result = 0;
    for (let i = 0; i < 1000000000; i++) {
      result += i;
    }
    return result + num;
  };

  // useMemoを使わないと、textを変更しても毎回重い処理が走る
  const memoizedResult = useMemo(() => heavyCalculation(count), [count]);

  return (
    <div style={{ padding: "20px" }}>
      <h2>useMemoサンプル</h2>
      <p>計算結果: {memoizedResult}</p>
      <button onClick={() => setCount((prev) => prev + 1)}>カウント +1</button>
      <div style={{ marginTop: "20px" }}>
        <input
          type="text"
          value={text}
          onChange={(e) => setText(e.target.value)}
          placeholder="テキストを入力してみよう"
        />
        <p>入力値: {text}</p>
      </div>
    </div>
  );
};

export default App;

🧠 解説

  • useMemo を使うことで、count が変わらない限り heavyCalculation は再実行されません。

  • text の変更時には再計算されず、パフォーマンスが大幅に向上します。

🔍 useMemoとuseCallbackの違い

フック 目的 戻り値
useMemo 値をメモ化 計算結果
useCallback 関数をメモ化 関数

👉 「値を覚える」→ useMemo
👉 「関数を覚える」→ useCallback

⚠️ 注意点

  • むやみに使うのは逆効果:useMemo自体にもメモリコストがある

  • 本当に重い処理や頻繁な再レンダー時のみ使用するのがおすすめ

  • コンポーネントを整理して最適化することが先決

🔄 ちなみにuseMemoを使わない場合のコード

以下のコードは、useMemo を使わずに重い処理をそのまま実行している例です👇

App.jsx
import React, { useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState("");

  // 🔥 重い処理(例:大きなループ)
  const heavyCalculation = (num) => {
    console.log("重い計算を実行中...");
    let result = 0;
    for (let i = 0; i < 1000000000; i++) {
      result += i;
    }
    return result + num;
  };

  // ❌ useMemoなし:毎回再計算される
  const result = heavyCalculation(count);

  return (
    <div style={{ padding: "20px" }}>
      <h2>useMemoなしの例</h2>
      <p>計算結果: {result}</p>
      <button onClick={() => setCount((prev) => prev + 1)}>カウント +1</button>

      <div style={{ marginTop: "20px" }}>
        <input
          type="text"
          value={text}
          onChange={(e) => setText(e.target.value)}
          placeholder="テキストを入力してみよう"
        />
        <p>入力値: {text}</p>
      </div>
    </div>
  );
};

export default App;

🧠 解説

  • text を入力しても、コンポーネント全体が再レンダーされるため
    → heavyCalculation() が 毎回実行 される

  • コンソールには、"重い計算を実行中..." が何度も表示される

  • 入力フィールドの操作(軽い処理)にも関わらず、重い計算が走ってしまうのが問題

🧭 まとめ

  • useMemo は、再レンダー時の無駄な再計算を防ぐためのフック

  • 重い処理や配列・オブジェクトの再生成に効果的

  • 適材適所で使うことが重要

🏁 最後に

useMemo はReactの「パフォーマンス最適化」を理解するうえで欠かせないフックです。
次のステップとしては、useCallback と組み合わせて使うことで、より高度な最適化が可能になります。

実際の開発では、「本当に再計算が必要なときだけ実行する」 という考え方が大切です💡
最後までご覧いただきありがとうございます。次はuseCallbackの復習をしようと思いますので、そちらにも付き合ってもらえると嬉しいです。それではまた次の記事でお会いしましょう。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?