バケツリレーの限界

深いところまで届けるということ

fleama の画面を暗くする「ダークモード」を付けることになりました。暗いかどうかは画面全体の話なので、いちばん外側で決めます。ところが、実際に色を変えたいのは価格の文字のようないちばん奥の部品です。

いまの fleama は、外側から順に App、ItemList、ItemCard、PriceTag と4段になっています。テーマを App で決めて PriceTag で使うには、間の ItemList と ItemCard にも渡してもらうしかありません。

<ItemList items={items} theme={theme} />

ItemList は受け取った theme を自分では使わず、そのまま ItemCard に渡します。ItemCard も使わず PriceTag に渡します。バケツリレーと呼ばれる形です。

何が辛いのか

動くには動きます。辛いのは、増えたときと変わったときです。

  • 途中の部品が theme を使っていないのに、props の型に theme を書かされる
  • 段が5段10段と深くなると、渡し忘れた1か所を探すのに時間が溶ける
  • あとで「文字サイズ」も共有したくなると、また全段に足すことになる
  • ItemList を別の場所で使い回そうとすると、要らない theme まで渡す羽目になる

つまり、途中の部品が「通り道」にされてしまうのが問題です。ItemList の仕事は商品を並べることであって、テーマを運ぶことではありません。

それでも一度は書いてみる

いきなり便利な仕組みから入ると、何が便利なのか分かりません。この回では、あえて4段のバケツリレーを自分の手で書きます。次の回から、この受け渡しを1本ずつ消していきます。

型は "light" | "dark" のユニオンにしておきます。文字列のままにすると "Dark" のような表記ゆれが通ってしまうためです。

演習

テーマを App から PriceTag まで、props で運びます。

ヒント

App.tsx
App.tsx
プレビュー

できているか

  • カードが3枚並んでいる
  • 3枚とも価格に dark のクラスが届いている
  • 価格が 円 付きで出ている
  • 帆布トートが並んでいる