propsのバケツリレー

値は必ず一段ずつ降りる

props は親から子へ、一段ずつしか渡せません。孫やひ孫へ一気に届ける近道はありません。

App owner を持っている └─ WorkSection └─ WorkList └─ WorkCard owner を表示したい

App が持っている値を WorkCard で使いたいとき、途中の WorkSectionWorkList も受け取って下へ渡す必要があります。自分では使わないのに、です。

この形を props のバケツリレー、英語では props drilling と呼びます。バケツを手渡しで運ぶように、途中の人が全員手を出さないと水が届かない、という様子から来ています。

実際に書くとこうなる

function WorkSection({ owner }) { return <WorkList owner={owner} />; } function WorkList({ owner }) { return ( <ul className="work-list"> {works.map((work) => ( <li key={work.id}> <WorkCard owner={owner} title={work.title} /> </li> ))} </ul> ); }

WorkSection の中に owner という文字は2回出てきますが、この部品は owner を1ミリも使っていません。受け取って、そのまま渡しているだけです。

何が困るのか

2階層くらいなら、むしろ分かりやすい仕組みです。値がどこから来たかを追うとき、上へたどれば必ず出どころに着きます。困るのは深くなってからです。

  • 渡す値を1つ足すたびに、途中の部品を全部書き直すことになる
  • 途中の部品の props が、自分に関係ない項目でふくらむ
  • 途中の1か所で渡し忘れると、いちばん下だけが静かに空になる。エラーは出ない

3つめが特にやっかいです。画面に何も出ないだけなので、どの階層で落としたのかを上から順に探すことになります。

逃げ道はあるが、まだ使わない

React には、この手渡しを飛ばして深いところへ値を届ける Context という仕組みがあります。ログイン中のユーザーやテーマの色など、画面のあちこちで使う値に向いています。ただし Context は「どこから来た値か」が読みづらくなる側面もあり、浅いバケツリレーを無理に置き換えると、かえって追えないコードになります。

だから入門のいまは、まず手渡しの形を体に入れます。Context は React 実践で扱います。手渡しが面倒だと感じた経験があるかどうかで、Context を学ぶときの理解の深さが変わります。

つまずきどころ

途中で名前を変えて渡してしまう間違いが多いです。<WorkList user={owner} /> と書いてしまうと、受け取る側は user で取り出さなければなりません。渡す名前と受け取る名前は必ず一致させます。

演習

途中の階層で止まっているバケツを、いちばん下まで届けます。

ヒント

App.jsx
WorkCard.jsx
WorkList.jsx
WorkSection.jsx
works.js
App.jsx
WorkCard.jsx
WorkList.jsx
WorkSection.jsx
works.js
プレビュー

できているか

  • 作品カードが3枚表示されている
  • カードに「あおい」が届いている
  • カードに作品名が表示されている
  • カードが work-list の中に入っている