この記事の最終更新日: 2025年6月7日
はじめに
React が Hooks を導入してから 6 年が経ちました。Custom Hook によってロジックの再利用が容易になり、Container / Presenter パターン(別名 Smart / Dumb コンポーネント) は過去の遺物だと語られることもあります。しかし 2024–2025 年に発表された多くのケーススタディでは、スケールする画面設計 と UX 改善 のために依然として有効であることが示されています。本記事では最新の知見を踏まえ、実装・テスト・パフォーマンス最適化まで網羅的に解説します。
TL;DR(忙しい方向けまとめ)
- Container = 何をやるか(データ取得・状態管理・副作用)
- Presenter = どう見せるか(純粋な UI 描画)
- Hooks でロジックを Custom Hook に抽出 → Container を最薄化するのが 2025 年流。
- 小規模 UI ではコストが上回るため 適材適所 で採用する。
- SSR・Suspense/React Server Components(RSC)時代でも “UI ロジック分離“ の原則は不変。
1. 歴史的背景と進化
年 | トピック | 概要 |
---|---|---|
2015 | Dan Abramov が Medium で提唱 | Presentational/Container という用語が広まる |
2018 | Hooks 登場 | useState / useEffect がクラスの代替に |
2021 | Redux Style Guide が “細かく connect せよ” を推奨 | コンテナ数を増やしてパフォーマンス改善 |
2023 | React 公式ドキュメント再構成 | Custom Hook + Composition を推奨しつつもパターン自体を否定せず |
2024–25 | ケーススタディで再評価 | 複雑 UI のアクセシビリティ・パフォーマンスチューニングに有用 |
ポイント: Hooks は Container / Presenter を“置き換えた”のではなく、“補完”している。
2. Container の責務(最新プラクティス)
- データフェッチ/キャッシュ:
react-query
,SWR
などと連携し、副作用を一箇所に集約。 - グローバルストアの購読:Jotai・Zustand へ書き込み/読み込み。
- 機能トグル:AB テストやフラグ管理ライブラリとの統合。
- アクセシビリティ状態の計算:読み上げモードやフォーカス管理。
- エラーバウンダリのラップ:UI 崩壊を局所化。
export const ProductListContainer = () => {
const { data: products, isLoading } = useQuery(['products'], api.fetchProducts);
const [filter, setFilter] = useAtom(productFilterAtom);
const filtered = useMemo(() => applyFilter(products, filter), [products, filter]);
return <ProductListPresenter products={filtered} isLoading={isLoading} onFilterChange={setFilter} />;
};
3. Presenter の責務
- 純粋関数コンポーネント (PFC):props → JSX への射影のみ。
- レイアウトとスタイル:CSS‑in‑JS(Emotion)・Tailwind CSS など。
- アクセシビリティ属性:
aria-*
、キーボード操作対応。 - アニメーション:Framer Motion / React‑Spring のみを扱う。
export const ProductListPresenter: FC<Props> = ({ products, isLoading, onFilterChange }) => {
if (isLoading) return <Spinner />;
return (
<section className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
{products.map((p) => (
<ProductCard key={p.id} product={p} />
))}
<FilterDrawer onChange={onFilterChange} />
</section>
);
};
4. Hooks 時代のベストプラクティス
- ロジックは Custom Hook へ抽出 → Container が 10 行程度に
- Presenter は memo 化 or
React.memo
で不要な再描画を防ぐ - Context × Presenter でツリー深度を気にせず UI 再利用
Custom Hook 例
export const useFilteredProducts = () => {
const { data: products } = useQuery(['products'], api.fetchProducts);
const [filter] = useAtom(productFilterAtom);
return useMemo(() => applyFilter(products, filter), [products, filter]);
};
5. いつ採用すべきか?チェックリスト
- 同一 UI をデータソース違いで複数画面に再利用したい
- アクセシビリティと UI テストを高い精度で行いたい
- パフォーマンスチューニング(メモ化/コード分割)を局所化したい
- デザインチームとエンジニアが職域分割したい
採用しない方が良いケース
- 画面がシンプルで、ステートが 1–2 個しか無い
- 制作スピード最優先のプロトタイピング段階
- GraphQL + Relay を利用している場合(※GraphQLはクエリ言語で、APIのレスポンスを必要な形で取得できる仕組み。Relayはそのクエリを効率的に扱うためのライブラリ)
fragment
単位でロジックとUIが共存し、Container / Presenter の役割分離が逆に煩雑になることがある
6. パフォーマンス最適化
テクニック | Container 側 | Presenter 側 |
---|---|---|
メモ化 | useMemo , useCallback で計算値保持 | React.memo で再レンダリング抑止 |
コード分割 | import() で Presenter を遅延ロード | Skeleton UI を返し UX 維持 |
SSR/RSC 対応 | fetch をサーバー実行 → preload() | クライアント部は PFC のみ |
7. テスト戦略(2025 年版)
- Presenter:Storybook + Playwright でビジュアル回帰
- Container:Jest + React Testing Library で副作用のモック
- Custom Hook:
@testing-library/react-hooks
によるユニットテスト
8. 移行シナリオ(既存の複合コンポーネントから段階的に)
- UI 描画部を Presenter に切り出し — props を明示的に整理
- 状態管理を Custom Hook へ — Container から呼び出す
- 副作用を SWR / React‑Query へ置換
- E2E テストをリグレッションモードで追加
9. よくある質問(FAQ)
Q. Hooks だけではダメ?
A. 小規模画面なら問題ないですが、UI とロジックが混在して長大化しやすい点と、再描画コストの局所化が困難になる点から、中規模以上ではパターン採用を推奨。
Q. Presenter にもローカル state を置いて良い?
A. UI 表示専用の“視覚的状態”(モーダル開閉、hover 状態など)は許容されます。
10. 参考文献・さらなる読み物(2023–2025)
- Dan Abramov, “Presentational and Container Components” (2015, updated 2021)
- Prophet Bestman, “React Container / Presentational Pattern” (2024)
- Carmatec Blog, “Best React Design Patterns to Know About in 2025” (2025)
- Plain English, “Understanding the Container / Presentational Pattern in React” (2025)
- TSH.io, “Container‑presentational pattern in React – why and how to use” (2023)
- Eluminous Technologies, “React Design Patterns 2024” (2024)
- Matan Borenkraout, “Why you should stop using the container/presentational pattern in Redux” (2021)
- StackOverflow QA, “Regarding Dan Abramov’s update about Presentational and Container” (2020)
まとめ
Container / Presenter パターンは Hooks 時代の今でも“設計の基礎体力” として有効です。Custom Hook や RSC と組み合わせ、UI とロジックの明確な境界を保つことで、保守性・テスタビリティ・パフォーマンス を高次元で両立できます。適材適所で導入し、2025 年の React 開発をさらにドライブしましょう。

大阪のエンジニアが書いているブログ。
コメント