モダンJavaScriptの基礎から始める挫折しないためのReact入門 60日コース | フォーム・コンポーネント設計 - DAY 39:Props Drilling

React 60日で身につけるReact
スポンサーリンク
スポンサーリンク
  1. DAY 39:Props Drilling 前半 ― 「深い階層にPropsを渡す」ときに何が起きるかを知る
  2. Propsを複数階層で渡すとはどういうことか
    1. 「親 → 子 → 孫 → ひ孫…」とバケツリレーのように渡していく
    2. 簡単な例:テーマカラーを深い階層のボタンまで渡す
  3. Props Drillingの問題点
    1. 1. 間のコンポーネントが「ただの通り道」になってしまう
    2. 2. Propsの数が増えると、管理が大変になる
    3. 3. コンポーネントの再利用性が下がる
  4. Contextの必要性 ― なぜ「別の仕組み」が欲しくなるのか
    1. 「どこからでも同じ値を参照したい」という欲求が生まれる
    2. Contextが解決しようとしていること
  5. この時点では無理にContextを使いません
    1. 「まずPropsで限界を感じる」ことが大事です
    2. 今は「Props Drillingを意識してコードを書く」ことが目標です
  6. DAY 39 前半のまとめ ― Props Drillingを「構造」として理解する
  7. DAY 39:Props Drilling 中盤 ― 実際のコードで「どこがつらいのか」を体感する
  8. Propsを複数階層で渡すミニアプリを作ってみる
    1. シナリオ:ログインユーザー情報を深い階層のボタンで使いたい
  9. 問題点をコードの「違和感」として感じてみる
    1. 1. コンポーネントの定義が「Propsだらけ」になっていく
    2. 2. 「責務の境界」がぼやけてくる
    3. 3. 機能追加・変更のときに「すべての階層」を意識しないといけない
  10. Contextの必要性を「こうなったら欲しくなる」という形で理解する
    1. 「間のコンポーネントを通さずに渡したい」という欲求が生まれる
    2. Contextがあればどうなるか(イメージだけ)
  11. この時点では無理にContextを使わない理由
    1. 「まずPropsで限界を感じる」ことが、学習としてはとても大事です
    2. 今やるべきことは「Props Drillingを意識してコードを書く」こと
  12. DAY 39 中盤のまとめ ― Props Drillingの「つらさ」をコードで体感する
  13. DAY 39:Props Drilling 後半 ― 「どこまでPropsで頑張るか」を自分で判断できるようになる
  14. Propsを複数階層で渡すこと自体は「悪」ではない
    1. 小さなアプリでは、Propsだけで十分なことが多いです
    2. 「今はPropsで書く」ことに意味がある
  15. 問題点を「設計のチェックポイント」として整理する
    1. Props Drillingが「危険信号」になるタイミング
    2. 問題点を「設計のアンチパターン」として意識する
  16. Contextの必要性を「設計の選択肢」として理解する
    1. Contextは「Props Drillingを減らすための選択肢」のひとつ
    2. 「今は使わない」と決めることも、立派な設計判断です
  17. DAY 39 後半版「Props Drilling設計チェックリスト」
    1. Propsを複数階層で渡すときのチェック
    2. 問題点を感じたときの問いかけ
    3. Contextの必要性を考えるタイミング
  18. DAY 39 後半のまとめ ― 「Propsでどこまで頑張るか」を自分で決められるようになる

DAY 39:Props Drilling 前半 ― 「深い階層にPropsを渡す」ときに何が起きるかを知る

DAY 39では、Reactでよく話題になる 「Props Drilling(プロップス・ドリリング)」 について学びます。 前半の学習項目は次の4つです。

  • Propsを複数階層で渡す
  • 問題点
  • Contextの必要性
  • この時点では無理にContextを使いません

ここでは、まだContextを実際に使うところまでは行かず、 「なぜContextという仕組みが必要になるのか」を理解するために、 Props Drillingの構造と問題点を、例題とコードを交えながら丁寧に見ていきます。

Propsを複数階層で渡すとはどういうことか

「親 → 子 → 孫 → ひ孫…」とバケツリレーのように渡していく

まず、Props Drillingとは何かをシンプルに言葉で説明します。

「本当に必要としているコンポーネントまで、間にいるコンポーネントを経由してPropsを渡し続けること」

です。

イメージとしては、

  • 親コンポーネントがある値や関数を持っている
  • それを、直接使いたいのは「孫コンポーネント」や「ひ孫コンポーネント」
  • でも、Reactでは「親 → 子 → 孫 → ひ孫…」という形でしか渡せない
  • そのため、間にいるコンポーネントも「受け取って、渡すだけ」のPropsを抱えることになる

という構造になります。

簡単な例:テーマカラーを深い階層のボタンまで渡す

次のような構成を考えてみます。

  • App:アプリ全体のテーマカラーを持っている
  • Layout:画面のレイアウトを担当する
  • Sidebar:サイドバーを表示する
  • UserMenu:ユーザーメニューを表示する
  • LogoutButton:ログアウトボタンを表示する(ここでテーマカラーを使いたい)

このとき、「テーマカラー」を LogoutButton まで渡したいとします。

function App() {
  const themeColor = "blue";

  return <Layout themeColor={themeColor} />;
}

function Layout({ themeColor }) {
  return (
    <div>
      <h1>アプリタイトル</h1>
      <Sidebar themeColor={themeColor} />
    </div>
  );
}

function Sidebar({ themeColor }) {
  return (
    <div>
      <p>サイドバー</p>
      <UserMenu themeColor={themeColor} />
    </div>
  );
}

function UserMenu({ themeColor }) {
  return (
    <div>
      <p>ユーザーメニュー</p>
      <LogoutButton themeColor={themeColor} />
    </div>
  );
}

function LogoutButton({ themeColor }) {
  return (
    <button style={{ color: themeColor }}>ログアウト</button>
  );
}
JSX

ここで実際にテーマカラーを使っているのは LogoutButton だけですが、 LayoutSidebarUserMenu も、 「themeColorを受け取って、そのまま次のコンポーネントに渡すだけ」 という役割を担わされています。

これが、典型的な Props Drilling の構造です。

Props Drillingの問題点

1. 間のコンポーネントが「ただの通り道」になってしまう

Props Drillingの一番の問題は、

「間にいるコンポーネントが、ただの通り道になってしまう」

ことです。

先ほどの例では、

  • Layout は本来「画面全体のレイアウト」を担当したい
  • Sidebar は「サイドバーの表示」を担当したい
  • UserMenu は「ユーザーメニューの表示」を担当したい

はずなのに、 それぞれが「themeColorを受け取って、次に渡す」という余計な責務を抱えています。

コードを読むときに、

  • 「このコンポーネントは何をしているのか?」
  • 「なぜこのPropsを受け取っているのか?」

を考えなければならず、読みやすさが下がります

2. Propsの数が増えると、管理が大変になる

Props Drillingが起きている状態で、 渡すPropsが1つだけならまだマシですが、 複数になると一気に大変になります。

例えば、次のような状態を想像してみてください。

  • themeColor
  • currentUser
  • onLogout

など、3つのPropsを LogoutButton に渡したいとします。

function App() {
  const themeColor = "blue";
  const currentUser = { name: "Taro" };
  const handleLogout = () => { /* ログアウト処理 */ };

  return (
    <Layout
      themeColor={themeColor}
      currentUser={currentUser}
      onLogout={handleLogout}
    />
  );
}

function Layout({ themeColor, currentUser, onLogout }) {
  return <Sidebar themeColor={themeColor} currentUser={currentUser} onLogout={onLogout} />;
}

function Sidebar({ themeColor, currentUser, onLogout }) {
  return <UserMenu themeColor={themeColor} currentUser={currentUser} onLogout={onLogout} />;
}

function UserMenu({ themeColor, currentUser, onLogout }) {
  return (
    <LogoutButton
      themeColor={themeColor}
      currentUser={currentUser}
      onLogout={onLogout}
    />
  );
}
JSX

このように、 「実際には使っていないのに、Propsとして受け取って次に渡すだけ」 というコードが増えていきます。

結果として、

  • コンポーネントの定義が長くなる
  • Propsの名前を変更したいときに、すべての階層を直さなければならない
  • バグが紛れ込みやすくなる

という問題が発生します。

3. コンポーネントの再利用性が下がる

Props Drillingが多いコンポーネントは、

「特定の親に強く依存した構造」

になりがちです。

例えば、SidebarthemeColorcurrentUser を受け取る前提で作られていると、

  • 別の画面で「シンプルなSidebarだけ使いたい」と思っても、 余計なPropsを渡さないといけない

という状態になり、再利用性が下がります。

重要なポイント:

Props Drillingは、「コンポーネントの責務を増やし、読みやすさ・保守性・再利用性を下げる」 という形で、じわじわと悪影響を与えます。

Contextの必要性 ― なぜ「別の仕組み」が欲しくなるのか

「どこからでも同じ値を参照したい」という欲求が生まれる

Props Drillingの問題を経験すると、 次のような欲求が自然と生まれます。

  • 「テーマカラーみたいな値は、どこからでも参照できたらいいのに」
  • 「ユーザー情報やログイン状態も、いちいちPropsで渡さずに使えたら楽なのに」
  • 「間のコンポーネントを通さずに、直接深いコンポーネントに渡したい」

この欲求に応えるために用意されているのが、 ReactのContext(コンテキスト)という仕組みです。

Contextが解決しようとしていること

Contextは、ざっくり言うと、

「ツリーの上の方で値を用意しておき、ツリーの下の方から直接その値を参照できるようにする仕組み」

です。

つまり、

  • App で「テーマカラー」や「現在のユーザー」をContextとして提供する
  • LogoutButton などの深い階層のコンポーネントが、 間のコンポーネントを経由せずに、そのContextを直接読む

ということができるようになります。

これにより、

  • Props Drillingを減らせる
  • 間のコンポーネントが「通り道」にならなくて済む
  • コンポーネントの責務がシンプルになる

というメリットが生まれます。

この時点では無理にContextを使いません

「まずPropsで限界を感じる」ことが大事です

ただし、DAY 39の時点では、 無理にContextを使わない方がよいです。

理由は、

  • Contextは便利ですが、仕組みが少し複雑で、初心者にはとっつきにくい
  • まずは「Propsでどこまでできるか」「どこで苦しくなるか」を体験した方が、Contextのありがたみが分かる
  • Props Drillingの構造と問題点を理解してからContextを見ると、「なぜ必要なのか」が腑に落ちる

からです。

今は「Props Drillingを意識してコードを書く」ことが目標です

DAY 39前半の段階で目指したいのは、

  • 「あ、ここはProps Drillingが起きているな」と気づけるようになること
  • 「このPropsは、このコンポーネントでは使っていないのに、次に渡すためだけに受け取っているな」と意識できること
  • 「将来的にはContextを使うと楽になりそうだな」と感じられること

です。

今はまだ、

「Propsで深い階層まで渡す」という基本の動きをしっかり体に覚えさせる段階

だと考えてください。

Contextは、 この「Propsでの限界」を感じたあとに学ぶと、 ずっと理解しやすくなります。

DAY 39 前半のまとめ ― Props Drillingを「構造」として理解する

DAY 39前半で身につけてほしいポイントは次の通りです。

  • Props Drillingとは、「本当に必要としているコンポーネントまで、間のコンポーネントを経由してPropsを渡し続けること」であること。
  • Propsを複数階層で渡すと、間のコンポーネントが「ただの通り道」になり、読みやすさ・保守性・再利用性が下がること。
  • Propsの数が増えると、すべての階層で同じPropsを受け渡ししなければならず、管理が大変になること。
  • こうした問題を解決するために、ReactにはContextという仕組みが用意されていること。
  • ただし、この時点では無理にContextを使わず、「Propsでどこまでできるか」「どこで苦しくなるか」を体験することが大事であること。

この「Props Drillingの構造と問題点」を理解しておくと、 今後Contextを学ぶときに、 「なぜこの仕組みが必要なのか」を自然に理解できるようになっていきます。


DAY 39:Props Drilling 中盤 ― 実際のコードで「どこがつらいのか」を体感する

DAY 39の中盤では、前半で言葉で理解した

  • Propsを複数階層で渡す
  • 問題点
  • Contextの必要性
  • この時点では無理にContextを使いません

を、実際のコードを通して「手触りのある理解」に変えることを目指します。 ここでは、少し現実的なミニアプリを題材にして、Props Drillingがどう発生し、どこがつらくなるのかをステップバイステップで見ていきます。

Propsを複数階層で渡すミニアプリを作ってみる

シナリオ:ログインユーザー情報を深い階層のボタンで使いたい

次のような構成のミニアプリを考えます。

  • App:ログイン中ユーザー情報を持っている
  • Layout:画面全体のレイアウト
  • Header:ヘッダー部分
  • UserArea:ユーザー関連の表示
  • ProfileCard:ユーザー情報を表示するカード
  • LogoutButton:ログアウトボタン(ここでユーザー名を使いたい)

「ログイン中ユーザーの名前を、深い階層の LogoutButton で表示したい」という状況です。

const mockUser = {
  id: 1,
  name: "山田太郎",
  email: "taro@example.com",
};

function App() {
  const [currentUser, setCurrentUser] = useState(mockUser);

  const handleLogout = () => {
    // 本当はAPI呼び出しなどをしますが、ここでは簡略化します
    setCurrentUser(null);
    alert("ログアウトしました");
  };

  return (
    <Layout currentUser={currentUser} onLogout={handleLogout} />
  );
}

function Layout({ currentUser, onLogout }) {
  return (
    <div>
      <Header currentUser={currentUser} onLogout={onLogout} />
      <main>メインコンテンツ</main>
    </div>
  );
}

function Header({ currentUser, onLogout }) {
  return (
    <header style={{ borderBottom: "1px solid #ccc", padding: "8px" }}>
      <h1>Reactアプリ</h1>
      <UserArea currentUser={currentUser} onLogout={onLogout} />
    </header>
  );
}

function UserArea({ currentUser, onLogout }) {
  return (
    <div style={{ float: "right" }}>
      <ProfileCard currentUser={currentUser} onLogout={onLogout} />
    </div>
  );
}

function ProfileCard({ currentUser, onLogout }) {
  if (!currentUser) {
    return <p>ゲストとして閲覧中です。</p>;
  }

  return (
    <div style={{ border: "1px solid #ddd", padding: "8px" }}>
      <p>ログイン中:{currentUser.name}</p>
      <LogoutButton currentUser={currentUser} onLogout={onLogout} />
    </div>
  );
}

function LogoutButton({ currentUser, onLogout }) {
  return (
    <button onClick={onLogout}>
      {currentUser ? `${currentUser.name} をログアウト` : "ログアウト"}
    </button>
  );
}
JSX

ここで実際に currentUseronLogout を使っているのは、

  • ProfileCard
  • LogoutButton

ですが、LayoutHeaderUserArea も、 「currentUser と onLogout を受け取って、そのまま次に渡すだけ」 という役割を担わされています。

これが、Props Drillingの典型的な構造です。

問題点をコードの「違和感」として感じてみる

1. コンポーネントの定義が「Propsだらけ」になっていく

上のコードをもう一度眺めてみると、 多くのコンポーネントが次のような形になっていることに気づきます。

function Layout({ currentUser, onLogout }) { ... }
function Header({ currentUser, onLogout }) { ... }
function UserArea({ currentUser, onLogout }) { ... }
function ProfileCard({ currentUser, onLogout }) { ... }
function LogoutButton({ currentUser, onLogout }) { ... }
JSX

特に LayoutHeaderUserArea は、

  • 自分自身では currentUser を表示していない
  • 自分自身では onLogout を呼んでいない
  • それでも「受け取って、次に渡すだけ」のためにPropsを抱えている

という状態です。

このようなコードが増えると、

  • コンポーネントの定義が「Propsの列」で埋まる
  • どのコンポーネントが本当にそのPropsを使っているのか、ぱっと見で分かりづらい
  • Propsの名前を変更したいときに、すべての階層を修正しなければならない

という「じわじわしたつらさ」が出てきます。

2. 「責務の境界」がぼやけてくる

本来の責務を考えると、

  • Layout:レイアウトを決める
  • Header:ヘッダーを表示する
  • UserArea:ユーザー関連の表示位置を決める
  • ProfileCard:ユーザー情報を表示する
  • LogoutButton:ログアウトボタンを表示する

という役割分担になっているはずです。

しかし、Props Drillingが増えると、

  • Layout は「レイアウト+ユーザー情報の通り道」
  • Header は「ヘッダー+ユーザー情報の通り道」
  • UserArea は「ユーザー表示位置+ユーザー情報の通り道」

というように、「通り道」という余計な責務が混ざってきます。

結果として、

  • 「このコンポーネントは何を担当しているのか?」
  • 「なぜこのPropsを受け取っているのか?」

を毎回考えないといけなくなり、読みやすさが下がります。

3. 機能追加・変更のときに「すべての階層」を意識しないといけない

例えば、

  • currentUser の型を少し変えたい
  • onLogout の名前を onUserLogout に変えたい

といった変更をしたくなったとします。

このとき、Props Drillingが起きている構造では、

  • App
  • Layout
  • Header
  • UserArea
  • ProfileCard
  • LogoutButton

と、すべての階層のコンポーネントを修正する必要が出てきます

これは、

  • 小さな変更でも「ツリー全体」に影響が広がる
  • バグが紛れ込みやすくなる
  • リファクタリングの心理的ハードルが上がる

という意味で、かなりの負担になります。

Contextの必要性を「こうなったら欲しくなる」という形で理解する

「間のコンポーネントを通さずに渡したい」という欲求が生まれる

ここまでのProps Drillingの例を見てくると、 自然と次のような気持ちが出てきます。

  • LayoutHeader は、ユーザー情報のことなんて知らなくていいのでは?」
  • UserArea も、ユーザー情報の通り道にならなくていいのでは?」
  • ProfileCardLogoutButton から、直接 currentUser を参照できたら楽なのに」

この「間のコンポーネントを通さずに、深いコンポーネントから直接値を参照したい」という欲求に応えるために用意されているのが、Contextです。

Contextがあればどうなるか(イメージだけ)

まだ実際のコードにはしませんが、 Contextを使ったときのイメージだけを言葉で描いてみます。

  • App で「現在のユーザー情報」と「ログアウト関数」をContextとして提供する
  • ProfileCardLogoutButton は、そのContextから直接 currentUseronLogout を読む
  • LayoutHeaderUserArea は、ユーザー情報のことを一切知らないまま、自分の責務に集中できる

こうなると、

  • Props Drillingが減る
  • 間のコンポーネントが「通り道」にならなくて済む
  • コンポーネントごとの責務がシンプルになる

というメリットが生まれます。

重要なポイント:

Contextは、「Props Drillingでつらくなったときに、それを解消するための仕組み」として登場します。 つまり、Props Drillingの痛みを知っているほど、Contextのありがたみが分かりやすくなります。

この時点では無理にContextを使わない理由

「まずPropsで限界を感じる」ことが、学習としてはとても大事です

DAY 39中盤の段階では、 あえてContextの具体的な使い方には踏み込みません。

理由は、

  • Contextは便利ですが、仕組みが一気に複雑になる
  • まずは「Propsでどこまでできるか」「どこで苦しくなるか」を体験した方が、Contextの必要性が腑に落ちる
  • Props Drillingの構造と問題点を理解してからContextを見ると、「なぜこの仕組みがあるのか」が自然に理解できる

からです。

今やるべきことは「Props Drillingを意識してコードを書く」こと

DAY 39中盤で目指したいのは、

  • 「このコンポーネントは、実際には使っていないPropsを受け取っていないか?」
  • 「このPropsは、どこまでバケツリレーされているのか?」
  • 「ここは将来的にContextを使うと楽になりそうだな」と感じられること

です。

今はまだ、

「Propsで深い階層まで渡す」という基本の動きをしっかり体に覚えさせる段階

だと考えてください。

Contextは、 この「Propsでの限界」を感じたあとに学ぶと、 ずっと理解しやすくなります。

DAY 39 中盤のまとめ ― Props Drillingの「つらさ」をコードで体感する

DAY 39中盤で定着させてほしいポイントは次の通りです。

  • Propsを複数階層で渡すと、間のコンポーネントが「受け取って、次に渡すだけ」の通り道になり、責務が増えてしまうこと。
  • Props Drillingが増えると、コンポーネントの定義がPropsだらけになり、読みやすさ・保守性・再利用性が下がること。
  • 機能追加や変更のときに、すべての階層のコンポーネントを修正しなければならず、バグが紛れ込みやすくなること。
  • こうしたつらさを経験すると、「間のコンポーネントを通さずに深いコンポーネントから直接値を参照したい」という欲求が生まれ、それに応える仕組みがContextであること。
  • この時点では無理にContextを使わず、「Propsでどこまでできるか」「どこで苦しくなるか」を意識しながらコードを書くことが、学習としてとても大事であること。

この「Props Drillingの構造とつらさ」を体で理解しておくと、 次にContextを学ぶときに、 「これはあの問題を解決するための仕組みなんだ」と自然に結びつけて考えられるようになっていきます。


DAY 39:Props Drilling 後半 ― 「どこまでPropsで頑張るか」を自分で判断できるようになる

DAY 39の後半では、

  • Propsを複数階層で渡す
  • 問題点
  • Contextの必要性
  • この時点では無理にContextを使いません。

という4つの学習項目を、「設計判断」という視点からもう一段深く掘り下げていきます。 ここでは、どこまでPropsで頑張るべきか/どこからが限界かを、自分で見極められるようになることを目標にします。

Propsを複数階層で渡すこと自体は「悪」ではない

小さなアプリでは、Propsだけで十分なことが多いです

まず強調しておきたいのは、

Propsを複数階層で渡すこと自体は、必ずしも悪いわけではない

ということです。

たとえば、

  • コンポーネント階層が浅い(親 → 子 → 孫くらい)
  • 渡すPropsが少ない(1〜2個程度)
  • アプリの規模が小さい

といった場合は、 Propsだけで十分にシンプルな設計を保てます。

実際、学習段階のミニアプリでは、

  • 親コンポーネントがStateを持つ
  • 子や孫コンポーネントがPropsとして受け取る

という構造だけで、かなりのことができます。

重要なポイント:

Props Drillingは「規模が大きくなったときに問題になりやすい」ものであり、 小さなアプリでは、Propsだけで十分なことが多いです。

「今はPropsで書く」ことに意味がある

この時点では、あえてContextを使わず、

「Propsでどこまで書けるか」を体験すること

に意味があります。

理由は、

  • Propsの基本的な流れ(親 → 子 → 孫)を体に染み込ませるため
  • 「どこでPropsがつらくなるか」を自分の目で確認するため
  • 後でContextを学ぶときに、「あのつらさを解消する仕組みなんだ」と結びつけられるようにするため

です。

いきなりContextに飛びつくよりも、

  • まずPropsで素直に書いてみる
  • そのうえで「ここはちょっと苦しいな」と感じる

というステップを踏んだ方が、 最終的に「状態管理のセンス」が育ちやすくなります。

問題点を「設計のチェックポイント」として整理する

Props Drillingが「危険信号」になるタイミング

Props Drillingが問題になり始めるタイミングを、 設計のチェックポイントとして整理してみます。

チェック1:階層の深さ

  • 3階層以上(親 → 子 → 孫 → ひ孫…)で同じPropsを渡し続けている
  • 特に、画面全体のレイアウトコンポーネントまで巻き込んでいる

この場合、 「間のコンポーネントが通り道になっていないか?」を疑う価値があります。

チェック2:Propsの数

  • 同じPropsを 3つ以上(例:currentUserthemeColoronLogout) 複数階層でバケツリレーしている

この場合、 コンポーネント定義が「Propsだらけ」になり、 読みやすさ・保守性が下がりやすくなります。

チェック3:責務の違和感

  • コンポーネントの中で、そのPropsを まったく使っていないのに、 次のコンポーネントに渡すためだけに受け取っている

この場合、

「このコンポーネントは、本来の責務以外に『通り道』という余計な役割を持たされていないか?」

と自分に問いかけてみるとよいです。

問題点を「設計のアンチパターン」として意識する

Props Drillingが増えた結果として起きるアンチパターンを、 もう一度整理しておきます。

  • 読みづらさの低下
    • コンポーネント定義がPropsだらけになる
    • 「このコンポーネントは何をしているのか?」が分かりづらくなる
  • 保守性の低下
    • Propsの名前や型を変えたいときに、すべての階層を修正しなければならない
    • 小さな変更でもツリー全体に影響が広がる
  • 再利用性の低下
    • 特定の親に強く依存したProps構造になり、別の画面で使い回しづらくなる

重要なポイント:

Props Drillingは、「動くけれど、長く付き合うにはつらいコード」を生みやすいアンチパターンです。 それを「危険信号」として認識できるようになることが、設計力の一歩目です。

Contextの必要性を「設計の選択肢」として理解する

Contextは「Props Drillingを減らすための選択肢」のひとつ

Contextは、

「ツリーの上の方で値を用意しておき、ツリーの下の方から直接その値を参照できるようにする仕組み」

でした。

設計の観点から見ると、Contextは次のような役割を持ちます。

  • Props Drillingを減らす
    • 間のコンポーネントを通さずに値を渡せる
  • 責務をシンプルにする
    • レイアウトコンポーネントなどが「通り道」にならなくて済む
  • グローバルに近い状態を扱いやすくする
    • テーマカラー・ログインユーザー・言語設定など、 アプリ全体で共有したい状態を扱いやすくする

ただし、Contextは「魔法の道具」ではなく、

「Propsでつらくなったときに、検討する価値がある選択肢」

だと捉えるのがちょうどよいです。

「今は使わない」と決めることも、立派な設計判断です

DAY 39の時点では、

「Contextを使わない」という選択を意識的に取る

ことが大事です。

これは、

  • 「今のアプリの規模なら、Propsだけで十分だ」と判断する
  • 「まずPropsで限界を感じてから、Contextを学ぶ」という学習方針を選ぶ

という、立派な設計判断です。

重要なポイント:

設計とは、「何を使うか」だけでなく、「何をまだ使わないか」を決めることでもあります。 今はContextを使わず、Propsでの状態管理をしっかり体に染み込ませる段階だと考えてください。

DAY 39 後半版「Props Drilling設計チェックリスト」

最後に、DAY 39後半の内容を、 実際にコードを書くときに使える「設計チェックリスト」としてまとめます。

Propsを複数階層で渡すときのチェック

  • 階層の深さ: 同じPropsを3階層以上で渡していませんか?
  • Propsの数: 同じPropsを3つ以上、複数階層でバケツリレーしていませんか?
  • 責務の違和感: そのコンポーネントは、そのPropsをまったく使っていないのに、 次に渡すためだけに受け取っていませんか?

問題点を感じたときの問いかけ

  • 「このコンポーネントは、本来何を担当するべきか?」
  • 「このPropsは、本当にこのコンポーネントで受け取る必要があるか?」
  • 「この状態は、もっと上の共通の親に置いた方がよくないか?」

Contextの必要性を考えるタイミング

  • 「間のコンポーネントを通さずに、深いコンポーネントから直接値を参照したい」と感じたとき
  • 「テーマカラー」「ログインユーザー」「言語設定」など、 アプリ全体で共有したい状態が増えてきたとき

ただし、DAY 39の時点では、

  • 「今はPropsで書く」
  • 「Propsでの限界を感じたら、Contextという選択肢があることを思い出す」

というスタンスで十分です。

DAY 39 後半のまとめ ― 「Propsでどこまで頑張るか」を自分で決められるようになる

DAY 39後半で身につけてほしいのは、次のような感覚です。

  • Propsを複数階層で渡すこと自体は悪ではなく、小さなアプリでは十分に有効であること。
  • Props Drillingが増えると、読みやすさ・保守性・再利用性がじわじわと下がるため、「危険信号」として認識できるようになること。
  • Contextは、Props Drillingでつらくなったときに検討する価値がある「設計の選択肢」であり、今はあえて使わずにPropsでの状態管理を体に染み込ませる段階であること。
  • 設計とは、「何を使うか」だけでなく、「何をまだ使わないか」を決めることでもあり、今はPropsでどこまで頑張るかを自分で判断できるようになること。

この「Props Drillingを意識した設計の目」が育ってくると、 Reactでフォームや画面を作るときに、 ただ動くコードではなく、長く付き合えるコードを書けるようになっていきます。

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