【実務・中級編】 コンポーネント合成とchildrenの活用 – React実践ガイド

「props地獄」を卒業しよう。コンポーネント合成(Composition)で実現する、疎結合なUIアーキテクチャ

現場でReactを書いていると、一度は経験するはずだ。「Props Drilling(プロップス・ドリリング)」。親から子、子から孫へと、バケツリレーのようにデータを渡すあの忌々しい作業。

「いや、Contextを使えばいいじゃん」――確かにそうかもしれない。だが、闇雲にContextへ逃げるのは、実は設計の敗北を意味することもある。

今日は、Reactにおける最も強力で、かつ最も誤解されやすい概念の一つ、「コンポーネント合成(Composition)」と`children`の活用について、現場の視点から深く掘り下げよう。

—

なぜ `children` なのか?ブラウザの裏側と設計思想

多くの初級者が「`children`は単なるDOMの入れ物」と捉えがちだが、Reactにおける`children`は、コンポーネントの「穴(スロット)」だ。

ブラウザのレンダリングエンジンは、`children`がどう構成されようと、最終的にはフラットなDOMツリーを構築する。しかし、Reactの仮想DOMレベルでは、`children`を活用することで「何を表示するか」の責務を親コンポーネントに委譲し、ラッパーコンポーネントを「どう表示するか」というプレゼンテーションに専念させることができる。

これこそが、疎結合なアーキテクチャの真骨頂だ。

実践:Layoutラッパーの作り方

よくある「カードUI」を例にしよう。ヘッダーやフッター、背景色を持つコンポーネントを、毎回propsでカスタマイズしていませんか? それ、`children`を使えばもっとエレガントに書ける。

import React, { ReactNode } from ‘react’;

// CardのProps定義:childrenを必須にするのがポイント
type CardProps = {
title: string;
children: ReactNode; // ReactNodeは、JSX、文字列、数値など何でも許容する最強の型
};

export const Card = ({ title, children }: CardProps) => {
return (

);
};

なぜこれが「良い」のか?

  • 再利用性: `Card`は中身の仕様を一切知らない。ただ「枠」として機能するだけだ。
  • 保守性: 中身のUIが変わっても、`Card`コンポーネントを修正する必要はない。
  • 疎結合: `Card`と中身のコンポーネントが依存関係を持たないため、テストも非常に楽になる。

—

さらに一歩先へ:「スロットパターン」の活用

もし、表示領域が複数ある場合はどうするか? 現場では、複数の`children`的なプロパティ(スロット)を定義する手法がよく使われる。

type LayoutProps = {
header: ReactNode;
main: ReactNode;
footer?: ReactNode; // フッターはオプションかもしれない
};

export const AppLayout = ({ header, main, footer }: LayoutProps) => {
return (

{header}

{main}

{footer &&

{footer}

}

);
};

// 利用側のコード
const MyPage = () => (
}
main={}
footer={}
/>
);

この手法を使えば、無理に階層を深くしてPropsを渡す必要は一切なくなる。「Props Drilling」が起きるのは、大抵の場合、コンポーネントが「親に依存しすぎている」からだ。

—

シニアからのTips:ここだけは注意しろ

最後に、実務でハマりやすいポイントを共有しておく。

1. `children`の型には`ReactNode`を使え: `JSX.Element`と書く人がいるが、それだとテキストノードや配列を弾いてしまうことがある。`ReactNode`が最も柔軟で安全だ。
2. 型安全を忘れるな: `React.FC`(FunctionComponent)の型定義を使う場合、React 18以降は`children`が暗黙的に含まれなくなった。明示的に`type`や`interface`で定義する癖をつけよう。
3. 過剰なラップは禁物: なんでもかんでもコンポーネント合成すればいいわけじゃない。あまりに細分化しすぎると、今度は「どこで何がレンダリングされているか」を追うのが困難になる。バランスこそが設計の醍醐味だ。

まとめ

コンポーネント合成は、Reactの最も「Reactらしい」書き方だ。
`children`を単なる「プロパティの一部」ではなく、「コンポーネントの柔軟な拡張ポイント」として意識するだけで、君の書くコードの質は劇的に変わるはずだ。

綺麗なコンポーネント設計は、チームの寿命を延ばす。さあ、明日のプルリクから、不要なpropsのバケツリレーを削除して、もっと自由な合成を楽しもうぜ。

もし分からないことがあれば、いつでもコードを見せに来てくれ。一緒に最高にクールなUIを作り上げよう。

コメント

タイトルとURLをコピーしました