Reactでコンポーネントを設計していると、「propsが10個以上並んでいる」構造に出会うことがある。 最初は意図的にシンプルに始めたはずのコンポーネントが、気づけば依存だらけの化け物関数になっている。

この問題は地味だが、レビュー観点としては非常に重要。設計ミスの早期発見・修正が可能な領域である。

propsが氾濫する理由とは

以下のような理由で、propsは増殖していく。

  • 状態とUIロジックが混在しやすい
  • コンポーネントの汎用化を試みて責務が膨張
  • 子から親へバケツリレーでpropsを渡すような構造
  • 同一の構造で一部だけ異なるUIが多発

典型的な「渡しすぎ構造」を以下に示す。

渡しすぎているprops構造
export const UserCard = ({ name, age, avatarUrl, onClick, onHover, isSelected, showEmail }: Props) => {
  return (
    <div onClick={onClick} onMouseEnter={onHover}>
      <img src={avatarUrl} />
      <h3>{name}</h3>
      {showEmail && <span>{age}</span>}
    </div>
  );
};
@Reviewer
props数が多く、構造が肥大化している。責務が整理されておらず、再利用やテストが困難。

props氾濫のレビュー観点

props氾濫の初期兆候:真偽値とイベントが多い

propsが増え始めたとき、最初に出てくるのが以下のような真偽値とイベント関数。

真偽値が肥大化した構造
<Card primary large hoverable selectable shadow onClick={handleClick} />
@Reviewer
真偽値のpropsが多く、variantパターンやCSS class構造で代替可能。責務を見直す余地がある。

このような真偽値の列は「状態の表現がprops依存になっている」ことの証拠。styleやvariantの責務と分離すべき。

改善パターン:propsオブジェクトをラップする

ラップ構造でpropsの粒度を下げる
export interface UserCardProps {
  user: {
    name: string;
    age: number;
    avatarUrl: string;
  };
  options: {
    showEmail: boolean;
    highlight?: boolean;
  };
  eventHandlers: {
    onClick: () => void;
    onHover?: () => void;
  };
}

このようにグルーピングすることで、propsの見通しがよくなり、意味のある単位で責務を分けやすくなる。

改善パターン:variant propsを吸収する

真偽値の多さは、variantでまとめられる場合が多い。

variantによる吸収構造
<Button variant="primary" size="large" />

CSSやスタイルユーティリティと併用することで、表示責務だけで完結するpropsに限定可能。

改善パターン:childrenやスロット構造への切り替え

表示内容が動的に変わる場合、propsで渡すより children を使う方が柔軟性が高い。

childrenパターン
<Card>
  <CardHeader title="ユーザー情報" />
  <CardBody>...</CardBody>
</Card>

状態管理の併用という手段もある

propsが多すぎて構造が破綻しそうな場合、React ContextやZustand、Recoilのような状態管理の導入も選択肢になる。 ただしこれは「propsを減らす手段」ではなく、「propsを引き回す必要をなくす構造」のための手段であり、むやみに導入すべきではない。

状態管理ライブラリとは

状態管理ライブラリは、ReactのuseStateでは管理しきれないようなグローバルまたはスコープ越えの状態共有を扱うためのツール群。代表例にRedux、Recoil、Jotai、Zustandなどがある。

補足:propsが多いけど状態管理を使いたくないとき

状態管理を導入せずにpropsを減らすには、以下のような手段がある:

  • propsを構造体でまとめる(前述)
  • childrenとslot構造に切り替える
  • compound component patternを採用する
  • 親の責務をcontextに逃がし、表示専用にpropsを渡す

まとめ

propsの渡しすぎは、開発速度が乗ってきた中盤以降で特に増えやすい。 しかしレビューで指摘できる余地は多く、props数、意味、構造、重複、責務をレビュー観点として確実に拾っていくことで、健全なコンポーネント設計が継続しやすくなる。

「多すぎるpropsは、その時点で設計の兆候異常」である。 レビューアーとしては、なぜこんなに多いのか?どうグルーピングすべきか?状態に逃がすべきか? を問う視点を持っていたい。