Reactの再レンダリングを制御「memo」「useMemo」「useCallback」のユースケース
Reactのパフォーマンス最適化における鍵を握るのが、不要な再レンダリングの抑制です。
アプリケーションが大規模化するにつれ、コンポーネントの描画コストは無視できないものになります。Reactにはこの再レンダリングを制御するための便利なフックやコンポーネントラッパーが用意されており、特に重要なのが React.memo、useMemo、useCallback です。
本記事では、これら3つの違いや適切な使い分け、注意点を初心者の方でも理解できるように、実例を交えながら丁寧に解説いたします。
コンポーネントの再レンダリングとは
Reactでは、状態やプロパティが変更されると該当コンポーネントが再レンダリングされます。
再レンダリングとは、仮想DOMの差分比較(Reconciliation)を行い、実際のDOMに変更を反映する処理です。
この一連の処理は小規模であれば問題になりませんが、以下のようなケースではパフォーマンスが低下します:
- 再レンダリング時に重い処理が走る(例:ソートやフィルター)
- 子コンポーネントが無関係な変更でも再描画される
- useEffectなどの副作用が無駄に実行される
こうした無駄な再レンダリングを防ぐ手段として登場するのが、memo、useMemo、useCallbackです。
React.memo:コンポーネント単位のメモ化
最も基本的かつ強力な最適化手法が React.memo です。
概要
React.memo は純粋関数コンポーネントをメモ化する高階コンポーネント(HOC)です。
同じ props であれば、再レンダリングをスキップしてくれます。
公式ドキュメント
基本使用例
tsximport React from 'react';
const Button = React.memo(({ onClick, children }: { onClick: () => void; children: React.ReactNode }) => {
console.log('Button rendered');
return <button onClick={onClick}>{children}</button>;
});
解説
この Button コンポーネントは React.memo によってラップされているため、props が変わらない限り再レンダリングされません。
以下のような親コンポーネントがあったとします:
tsxexport const Parent = () => {
const [count, setCount] = React.useState(0);
const handleClick = () => {
console.log('Clicked');
};
return (
<>
<p>Count: {count}</p>
<Button onClick={handleClick}>Click me</Button>
<button onClick={() => setCount(count + 1)}>Increment</button>
</>
);
};
このとき、handleClick が新しい参照になるため、Button は再レンダリングされます。これを防ぐには後述の useCallback が必要です。
useCallback:関数の参照を固定する
useCallback は関数をメモ化し、不必要な再生成を防ぐフックです。
公式ドキュメント
Hooks API Reference - useCallback
使用例
tsxconst handleClick = useCallback(() => {
console.log('Clicked');
}, []);
解説
第二引数の依存配列が変わらない限り、handleClick は常に同じ関数の参照を返します。
memo と useCallback を組み合わせると、無駄な再レンダリングを完全に防ぐことができます。
useMemo:値のメモ化
useMemo は計算結果をメモ化するためのフックです。
レンダリングごとに実行される処理を避け、前回の値を再利用することでコストを削減します。
公式ドキュメント
基本例
tsxconst sortedList = useMemo(() => {
return list.sort((a, b) => a.localeCompare(b));
}, [list]);
注意点
- 関数の副作用があるものには使わない(useEffectに分離すべき)
- 計算が軽量な場合は不要
使い分けの考え方と整理表
以下のように整理するとわかりやすくなります:
| 機能 | メモ化対象 | 再評価条件 | 主な用途 |
|---|---|---|---|
React.memo | コンポーネント | propsが変わる時 | コンポーネント再レンダリング防止 |
useCallback | 関数 | 依存配列が変わる時 | 関数の再生成防止(memoと併用) |
useMemo | 計算値 | 依存配列が変わる時 | 重い計算結果のキャッシュ |
よくあるパフォーマンス改善パターン
フィルターや検索の処理
tsxconst filteredItems = useMemo(() => {
return items.filter((item) => item.includes(keyword));
}, [items, keyword]);
子コンポーネントのイベントハンドラー
tsxconst handleLike = useCallback(() => {
onLike(itemId);
}, [itemId, onLike]);
過剰な最適化に注意
以下のようなケースでは逆にパフォーマンスが悪化することもあります:
useMemoによる不要なキャッシュuseCallbackによる不要な関数ラップReact.memoによる比較コストが高すぎる(deep equalityなど)
「本当にコストが高いか?」を計測した上で適用することが重要です。
開発者ツールでの確認
React DevTools を使えば、コンポーネントの再レンダリング状況を視覚的に確認できます。
コンポーネントを選択し、Render Count や Props の変更履歴を確認すると、適切にメモ化されているかが一目で分かります。
総まとめ
本記事では、Reactアプリケーションの再レンダリングを制御するために不可欠な3つの仕組みをご紹介しました。
React.memo:コンポーネント単位で再レンダリングを防ぐuseCallback:関数の再生成を防ぐuseMemo:計算値の再評価を防ぐ
適切な使い分けを実践することで、よりレスポンスの良いUIを構築することが可能になります。
ただし、過剰な最適化は逆効果となる可能性もあるため、「必要な場所だけに使う」意識が大切です。
最後までご覧いただきありがとうございました。
articleReact クリーンアーキテクチャ実践:UI・アプリ・ドメイン・データの責務分離
articleReact フック完全チートシート:useState から useTransition まで用途別早見表
articleReact 開発環境の作り方:Vite + TypeScript + ESLint + Prettier 完全セットアップ
articleReact とは? 2025 年版の特徴・強み・実務活用を一気に理解する完全解説
articleESLint を Yarn + TypeScript + React でゼロから構築:Flat Config 完全手順(macOS)
article【徹底比較】Preact vs React 2025:バンドル・FPS・メモリ・DX を総合評価
articleZustand の状態管理を使ったカスタムフック作成術
articleJest で Hooks(useState / useEffect)をテストする方法
articleReact × TypeScript:Hooks とコンポーネントの型安全な書き方
articleuseStoreフック徹底解説:Zustandの基本操作をマスターしよう
articleReactのSuspense × useTransitionを使って滑らかなUXを実現する方法
articleReact Custom HooksのuseCallbackの基本と使い方
articlePHP 基本文法を 90 分で速習:型宣言・null 合体・スプレッド構文の実践
articleHaystack チートシート:主要クラス・関数・CLI コマンド一枚まとめ
articleNotebookLM 活用事例:営業提案書の下書きと顧客要件の整理を自動化
articleGrok RAG 設計入門:社内ドキュメント検索を高精度にする構成パターン
articlegpt-oss 運用監視ダッシュボード設計:Prometheus/Grafana/OTel で可観測性強化
articleNode.js 標準テストランナー完全理解:`node:test` がもたらす新しい DX
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来