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を構築することが可能になります。
ただし、過剰な最適化は逆効果となる可能性もあるため、「必要な場所だけに使う」意識が大切です。
最後までご覧いただきありがとうございました。
articleESLint を Yarn + TypeScript + React でゼロから構築:Flat Config 完全手順(macOS)
article【徹底比較】Preact vs React 2025:バンドル・FPS・メモリ・DX を総合評価
article既存 React プロジェクトを Preact に移行する完全ロードマップ
articleReact 開発を加速する GitHub Copilot 活用レシピ 20 選
articleReact vs Preact 2025 年版 - パフォーマンス・機能・エコシステム完全比較
articleMotion(旧 Framer Motion)入門:React アニメーションを最速で始める
articleZustand の状態管理を使ったカスタムフック作成術
articleJest で Hooks(useState / useEffect)をテストする方法
articleReact × TypeScript:Hooks とコンポーネントの型安全な書き方
articleuseStoreフック徹底解説:Zustandの基本操作をマスターしよう
articleReactのSuspense × useTransitionを使って滑らかなUXを実現する方法
articleReact Custom HooksのuseCallbackの基本と使い方
articleJotai 運用ガイド:命名規約・debugLabel・依存グラフ可視化の標準化
articleZod vs Ajv/Joi/Valibot/Superstruct:DX・速度・サイズを本気でベンチ比較
articleYarn でモノレポ設計:パッケージ分割、共有ライブラリ、リリース戦略
articleJest を可観測化する:JUnit/SARIF/OpenTelemetry で CI ダッシュボードを構築
articleGitHub Copilot 利用可視化ダッシュボード:受容率/却下率/生成差分を KPI 化
articleWeb Components vs Lit:素の実装とフレームワーク補助の 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 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来