状態やコンポーネントを、Featureという型にまとめて、アプリケーションコンポーネントに渡す
参考
miyamonz.iconが関わってる、ドロワーあたりの説明する
Three.jsをreactで書ける
表示されてるポーズが草だったmrsekut.icon
デモ
平凡なテーブル上のTODOタスクアプリ
絞り込み機能がある
素朴な実装と、featureという単位を導入した実装の2つが入ってます
Reactの状態の運び方、という観点から、4段階で説明する。
1〜2までは、歴史的な経緯
3は、普通にモジュールをいい感じに扱うことを意識する一般的なプログラミング
4が、今回miyamonz.iconが発表したいこと
第一段階:プロップのバケツリレー
https://scrapbox.io/files/640e0b4fd548c7001b8938c3.png
問題
状態を複数のコンポーネントで使いたい
いちいち親から渡す必要があって面倒だった
解決策
hooks, contextを使う
すげえ雑に言うと、useStateをコンポーネント外でもできるようにしたようなやつ
もっといろいろできるのだが、初めて知った人はそのような理解でいいと思う
https://gyazo.com/934672985cfa3b369bc2ad47e4d873bc
https://scrapbox.io/files/640e0b751bf7d4001bd945ca.png
prop経由で渡すか、hooks経由で横挿しするかの選択肢がある
miyamonz.iconの考え
読んでわかれば何でも良し
プログラミング言語を自然言語としても読んで、読みやすいか(認知負荷が低くなっているか)を大事にする
状態のハンドリングに限らず大事
割と積極的にjotaiで横差しする
自前のinputみたいなのを、親にonChangeとかで伝えるの、実現したいことに対して本質的ではない
ファイルをまたぐような規模になるときは、jotaiのatomをimportするより、props経由で渡したほうが良いのではないかと検討する
第二段階:状態の散乱
アプリケーションコンポーネントのいろんな箇所で状態に関するものを扱う
https://gyazo.com/dfa57fc06be175040951328748dce313
問題
状態は散らばる
最初のうちは困らない
いろんなファイルから、特定の状態をimportすると、スパゲッティになってくる
解決策(の一つ)
ファイルスコープで隠蔽する
状態と、状態を使うコンポーネントを同一ファイルに置く
コンポーネントは複数ある場合もある
コンポーネントのみをexportする
なるたけコンポーネント等だけをアプリケーションコンポーネント側は使う
https://gyazo.com/e44068624dc1b51a20caadcbd03ea7a3
demo1のメモmrsekut.icon
atomは公開しない
関数をatomに入れてる
setする関数と、atomを使ったComponentを公開する
filterByCompletedFnAtom, SelectCompletedConditionの組や、その中の要素が増えた時にごちゃごちゃになるという問題点
次の問題
第三段階:アプリケーションコンポーネント上にコンポーネントが散らばる
アプリケーションコンポーネント(図の左側)上で、修正する、触る箇所が多い
解決策
モジュールからimportして、アプリケーションコンポーネントがconsumeする情報を型として表す
プロパティを明示的な名前にすることが大事
https://gyazo.com/10a323bdafe7546f84e0ea4c1c5d0ca2
このまとまりは、実際のケースに沿って適切に付ける必要がある
featureという名前を使うと意味が納得しやすいmiyamonz.icon(経験則)
↑この解決策を行ったものが第四段階
第四段階:featureでまとめて、これで受け渡す
各々の作りたいアプリケーションコンポーネントに基づいて、適切な型、プロパティ名を定めて、そのオブジェクトを渡す
これがうまくハマるとかなり良い
凝集度が高く
似た機能の追加や削除がしやすい
読む人が理解しやすい
feature flagをかんたんに作れるmrsekut.icon
featureが横のfeatureを見ることもありそう
発展
featureのオブジェクトをそのまま取ってくるのではなく、featureを返す関数としてやる
実行時に必要な情報を元にfeatureを作る必要がある時とか
これはrender hooks パターンの発展型ともみなせる
問題点
以上の概念を事前に説明抜きでコードを読むとピンとこないかも
簡単なテストコードがあれば難しくはないと思う。
ちょっとしたfeatureを用意して代入した例とかをstorybookで書いとくとか
若干複雑?
でも、それはアプリケーションコンポーネントの複雑さを対処するために発生したもので、妥当なコストのようにmiyamonz.iconは思える
アプリケーションコンポーネント上に、機能に関するものが散らばってて、バラバラに読みに行ったり、結合し忘れ等のミスが発生しやすい複雑さと比べれば、単純になってる…んじゃないかな
ふりかえり
仕事上のコードでの問題意識から、featureという単位でまとめて見通しが良くなった、という経験をしたのだが
結果だけを見ると、これは凝集度を高めて、結合度を下げるといった、一般的なプラクティスの一種とも言える
react componentや状態も、オブジェクトでまとめて受け渡したら快適になったぜ!
みんなもやってみてフィードバックしてくれ、という話でしたmiyamonz.icon