React PR

【React入門】useMemoで爆速レンダリング!5分で使いこなす方法

【React入門】useMemoで爆速レンダリング!5分で使いこなす方法
記事内に商品プロモーションを含む場合があります

こんにちは!
Reactを使ってWebアプリケーションを作っていると、パフォーマンスの問題に直面することがありますね。
特に、複雑な計算や大量のデータを扱う場合、アプリの動作が遅くなることがあります。
そんなときに役立つのが、ReactのuseMemoフック。

useMemoは、計算結果を記憶しておく機能です。
簡単に言えば、同じ計算を何度も繰り返さないようにする賢い方法なんです。
これを使うと、アプリの動作が速くなることがあります。

でも、すべての場面でuseMemoを使えばいいというわけではありません
使い方を間違えると、かえってパフォーマンスが悪くなることもあるんです。
だからこそ、正しい使い方を学ぶことが大切なんですね。

この記事では、useMemoの基本から実践的な使い方まで、順を追って説明していきます。
Reactを勉強し始めたばかりの方でも理解できるよう、なるべくわかりやすい言葉で解説していきますね。

この記事を読めば、以下のようなことがわかるようになります。

この記事でわかること
  • useMemoフックの基本的な使い方
  • パフォーマンス改善にどう役立つのか
  • 実際のコード例を通じた活用方法
  • 使用する際の注意点

React環境がない方はこちらも参考にしてください。

【たった1分】React×Vite×TypeScriptで高速ビルド環境を構築する方法
【たった1分】React×Vite×TypeScriptで高速ビルド環境を構築する方法こんにちは! 今日は、React、Vite(ヴィート)、TypeScriptを使用して、たった1分で高速にビルド環境を構築する方法につ...

useMemoとは?

useMemoは、Reactのフックの1つです。
フックって聞くと難しそうに感じるかもしれませんが、簡単に言えば「特別な機能を使うためのおまじない」みたいなものです。

useMemoの主な役割は、計算結果を記憶しておくことです。
これって、どういう意味なのでしょうか?
例えば、複雑な計算をする関数があったとします。
普通なら、その関数は呼び出されるたびに計算を実行します。
でも、useMemoを使うと、一度計算した結果を覚えておいて、同じ条件なら前回の結果をそのまま使い回してくれるんです。


const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

ここで、computeExpensiveValueは時間のかかる計算をする関数です。
[a, b]の部分は「依存配列」と呼ばれ、この値が変わったときだけ計算をやり直します。

これを使うと、どんなメリットがあるのでしょうか?
まず、無駄な計算を減らせるので、アプリの動作が速くなります。
特に、データが大量にある場合や、複雑な計算をする場合に効果を発揮します。

useMemoの使用シーン

useMemoはパワフルなツールですが、どんな場面で使えば効果的なのでしょうか?
ここでは、useMemoが特に役立つ2つの主要な使用シーンを見ていきましょう。

計算コストの高い処理

1つ目は、時間のかかる計算を行う場合です。
例えば、大量のデータを扱うときや、複雑な数学的計算を行うときがこれに当たります。

具体的な例を挙げてみましょう。
1万件のユーザーデータがあって、その中から特定の条件に合うユーザーを探す処理を考えてみてください。
こんな感じのコードになるでしょう:


const filteredUsers = useMemo(() => {
  return users.filter(user => user.age > 30 && user.isActive);
}, [users]);

この場合、usersデータが変わらない限り、フィルタリング処理は一度だけ実行されます。
データが大量にある場合、これだけでもかなりの時間短縮になりますね。

子コンポーネントへの最適化

2つ目は、子コンポーネントに渡すデータの最適化です。
Reactでは、親コンポーネントが再レンダリングされると、その子コンポーネントも再レンダリングされます。
でも、渡すデータが変わっていないのに再レンダリングするのは無駄ですよね。

こんな場合にuseMemoが役立ちます:


const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

return (
  <ChildComponent value={memoizedValue} />
);

こうすることで、abが変わらない限り、ChildComponentは不要な再レンダリングを避けられます。

ただし、すべての props にuseMemoを使う必要はありません。
計算コストが低い場合は、普通に値を渡す方が効率的なこともあります。

useMemoを実際に動かしてみる

さて、ここからはuseMemoの実践的な使用例を見ていきましょう。
具体的なコードを通じて、useMemoがどのように役立つのか、そしてどのように使うのかを学んでいきます。

フィボナッチ数列の計算を例に取ってみます。
フィボナッチ数列は、計算に時間がかかる典型的な例です。

FibonacciCalculator.tsx

import { useState, useMemo } from "react";

function FibonacciCalculator() {
  const [inputNum, setInputNum] = useState<string>("10");
  const [calcNum, setCalcNum] = useState<number>(10);

  const fibonacci = useMemo(() => {
    if (Number.isNaN(calcNum)) return null;
    const fib = (n: number): number => {
      if (n <= 1) return n;
      return fib(n - 1) + fib(n - 2);
    };
    console.log("フィボナッチ数を計算中...");
    return fib(calcNum);
  }, [calcNum]);

  const handleCalculate = () => {
    const num = parseInt(inputNum);
    if (!isNaN(num)) {
      setCalcNum(num);
    }
  };

  return (
    <div>
      <input
        type="number"
        value={inputNum}
        onChange={(e) => setInputNum(e.target.value)}
      />
      <button onClick={handleCalculate}>計算</button>
      <p>
        フィボナッチ数({calcNum}):{fibonacci}
      </p>
    </div>
  );
}

export default FibonacciCalculator;
main.tsx

import ReactDOM from "react-dom/client";
import FibonacciCalculator from "./FibonacciCalculator.tsx";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <FibonacciCalculator />
);

この例では、useMemoを使ってフィボナッチ数を計算しています。
入力値が変わらない限り、計算結果はメモ化されて再利用されます

実際にこのコンポーネントを使用すると、同じ数値で複数回計算ボタンを押しても、コンソールログは1回しか表示されないはずです。
これがuseMemoによるメモ化の効果です。

数値を変更して計算ボタンを押すと、新しい計算が行われ、結果が更新されます。
この例を通じて、useMemoが重い計算の最適化にどのように役立つか、より実感できるのではないでしょうか。

useMemoを使用する際の注意点

useMemoは強力なツールですが、適切に使用しないと思わぬ問題を引き起こす可能性があります。
ここでは、useMemoを使用する際の重要な注意点について説明します。

過剰な最適化を避ける

useMemoを使用すると、確かにパフォーマンスが向上する場合がありますが、すべての場所で使用すべきではありません
過剰な最適化は、かえってアプリケーションの複雑さを増し、メンテナンスを難しくする可能性があるんです。

以下のような場合は、useMemoの使用を避けた方が良いでしょう:

単純な計算や軽い処理

例えば、配列の長さを取得するだけなら、useMemoは不要です。


// 良くない例
const arrayLength = useMemo(() => array.length, [array]);

// 良い例
const arrayLength = array.length;

プリミティブ値の生成

文字列や数値などの単純な値を生成する場合も、useMemoは過剰です。


// 良くない例
const greeting = useMemo(() => `こんにちは、${name}さん`, [name]);

// 良い例
const greeting = `こんにちは、${name}さん`;

依存配列の正しい使用

useMemoの依存配列は非常に重要です。
正しく設定しないと、期待通りの動作をしない可能性があります。

必要なすべての依存関係を含める

計算に使用するすべての変数を依存配列に含めましょう。


// 良くない例(ageが変更されても再計算されない)
const userInfo = useMemo(() => `${name}(${age}歳)`, [name]);

// 良い例
const userInfo = useMemo(() => `${name}(${age}歳)`, [name, age]);

不要な依存関係を含めない

計算に関係のない値を依存配列に含めると、不要な再計算が発生します。


// 良くない例(unrelatedValueが変更されるたびに再計算される)
const expensiveResult = useMemo(() => expensiveCalculation(a, b), [a, b, unrelatedValue]);

// 良い例
const expensiveResult = useMemo(() => expensiveCalculation(a, b), [a, b]);

関数を依存配列に含める場合の注意

関数を依存配列に含める場合、その関数が再生成されないよう注意が必要です。
useCallbackと組み合わせて使用するのが一般的です。


const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

const memoizedResult = useMemo(() => {
  return expensiveComputation(memoizedCallback);
}, [memoizedCallback]);

適切な場所で適切に使用することが、useMemoを効果的に活用するコツです
過剰な最適化は避け、本当に必要な場所でのみ使用しましょう。
そして、依存配列の設定には細心の注意を払いましょう。

これらの注意点を守ることで、useMemoを効果的に使用し、アプリケーションのパフォーマンスを向上させることができます。

useCallbackとの違い

Reactを学んでいると、useMemoと似たような機能を持つuseCallbackというフックに出会うことがあります。
この2つは似ているようで異なる用途があります。
ここでは、useMemouseCallbackの違いを明確にし、それぞれをどのような場面で使うべきかを説明します。

基本的な違い

useMemoは値をメモ化するのに対し、useCallbackは関数自体をメモ化します
これが最も重要な違いです。

  • useMemo:計算結果(値)をメモ化
  • useCallback:関数自体をメモ化

例えば、以下のように使います:


// useMemoの例
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

// useCallbackの例
const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

使用する場面の違い

それぞれのフックは、異なる場面で活躍します。

useMemoの使用場面
  • 計算コストの高い処理の結果をメモ化する場合
  • オブジェクトや配列を生成し、それを子コンポーネントにpropsとして渡す場合
useCallbackの使用場面
  • イベントハンドラ関数を子コンポーネントにpropsとして渡す場合
  • 依存配列に含まれる関数をuseEffectなどの他のフックで使用する場合

パフォーマンスへの影響

両方のフックはパフォーマンス最適化のために使用されますが、その効果は状況によって異なります。

  • useMemoは計算結果をメモ化するため、重い計算を避けるのに有効です。
  • useCallbackは関数の再生成を防ぐため、子コンポーネントの不要な再レンダリングを避けるのに有効です。

ただし、どちらのフックも使用にはコストがかかります
メモ化自体にも処理時間とメモリが必要なので、軽い処理や単純な関数には使用を避けた方が良いでしょう。

使い分けのポイント

  1. 計算結果をメモ化したい場合はuseMemo
  2. 関数自体をメモ化したい場合はuseCallback
  3. 子コンポーネントに渡すpropsが頻繁に変わる場合、適切な方を選択
  4. useEffectの依存配列に関数を含める場合はuseCallbackを検討

結局のところ、useMemouseCallbackはどちらも最適化のためのツールです。
適切な場面で適切に使うことが大切です。
過剰な最適化は避け、本当に必要な場所でのみ使用するよう心がけましょう。

これでuseMemouseCallbackの違いが理解できたのではないでしょうか。
次の章では、これまでの内容をまとめ、useMemoの使用に関する最終的なアドバイスを提供します。

キャリア形成/給与還元
ひとつひとつ真摯に向き合う企業
ONE_WEDGE社員募集

株式会社 ONE WEDGEでは、新たな仲間を募集しています!

私たちと一緒に、革新的で充実したキャリアを築きませんか?
当社は、従業員が仕事と私生活のバランスを大切にできるよう、充実した福利厚生を整えています。

  • 完全週休2日制(土日休み)で、祝日や夏季休暇、年末年始休暇もしっかり保証!
  • 様々な休暇制度(有給、慶弔、産前・産後、育児、バースデー休暇)を完備!
  • 従業員の成長と健康を支援するための表彰制度、資格取得支援、健康促進手当など!
  • 生活を支えるテレワーク手当、記事寄稿手当、結婚祝金・出産祝金など、様々な手当を提供!
  • 自己啓発としての書籍購入制度や、メンバー間のコミュニケーションを深める交流費補助!
  • 成果に応じた決算賞与や、リファラル採用手当、AI手当など、頑張りをしっかり評価!
  • ワークライフバランスを重視し、副業もOK!

株式会社 ONE WEDGEでは、一人ひとりの従業員が自己実現できる環境を大切にしています。
共に成長し、刺激を与え合える仲間をお待ちしております。
あなたの能力と熱意を、ぜひ当社で発揮してください。
ご応募お待ちしております!

ホームページ、採用情報は下記ボタンからご確認ください!

応募、ご質問など、LINEでお気軽にご相談ください♪

まとめ

  1. 基本機能
    • useMemoは計算結果をメモ化し、不要な再計算を防ぎます。
  2. 主な使用シーン
    • 計算コストの高い処理
    • 大量データの加工
    • 子コンポーネントへのprops最適化
  3. 注意点
    • 過剰な使用は避ける
    • 依存配列を正しく設定する
    • 軽い処理には不要
  4. 使い方のコツ
    • パフォーマンス問題が実際に発生してから使用を検討
    • React Developer Toolsなどで計測しながら最適化

useMemoは、Reactアプリケーションのパフォーマンスを向上させる強力なツールです。
しかし、useMemoは万能薬ではありません。
適切な場面で適切に使うことが重要です。
パフォーマンスと可読性のバランスを取りながら、必要な場所で効果的に使用しましょう。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です