re-ducksを学ぶ
自分は ducks パターンが死ぬほど嫌いでして、どんなプロジェクトであっても導入すべきでないパターンだと思っています。
1 ファイルがやたら長くなるし、そのせいで保守性も低くなるし、その割に制限は強いと、正直良い点がないとすら思っています。
とはいえ、元の redux のフォルダ構成が辛い、という気持ちもわからなくもないです。
selector を組みたい場合など、確かにどこに selector を切れば良いのか、難しいですよね。
また redux-saga などを組み込んだ場合、sagas フォルダを切ることになりますが。
reducer や saga が特定の action しか呼ばない構成になっている場合、フォルダをあっちこっちまたぐというのは確かに非効率に感じる人もいると思います。
そんな中、最近妙に re-ducks という考え方を目にするようになってきたので、ちょっと調べてみました。
re-ducks とは
docks と通常の redux のフォルダ構成を足して 2 で割って、少し機能を追加した感じです。
考え方自体はわかりやすいですね。
フォルダ構成
duck/
├── actions.js
├── index.js
├── operations.js
├── reducers.js
├── selectors.js
├── tests.js
├── types.js
├── utils.js
要するに ducks パターン時の各 duck ファイルの各要素をファイル分割しただけですね。
redux-saga とか redux-observables を導入する場合は、各 duck フォルダに sagas や epics ファイルを切る感じですね。
各要素について
actions
その duck 内で使用される action が集約されます。
index
operations と selectors を export します。
他の duck で types を使用するケースでは types も export するみたいです。
action は export しないのがポイントですね。
operations
action をラップするみたいです。
複数の action を叩くケースでは、複数の action を叩くための operation を切るみたいです。
container の肥大化を抑える目的がありそうですね。
reducers
言わずもがな、reducer です。
selectors
store から必要な値のみを引っ張ってくる箇所です。
operations 同様、container の肥大化を抑える目的がありそうです。
tests
ここが re-ducks の一番大きなメリットみたいです。
action と reducer を組み合わせたテストを行う場合、ここに記述したら良いよ、という考え方みたいです。
確かに、元の redux のパターンではこのファイルが浮いちゃうので、これは合理的かつ強いですね。
types
action 名を記述します。
型を書く場所ではないので注意しましょう。
中~大規模なプロジェクトに向いているとの触れ込みでしたが、確かに固そうな考え方だなーと。
プロジェクトの規模が大きくなると、必然的に container が肥大化していくため、そこを抑えるために考えられたんだろうなという印象を受けました。
ただ一方、container 単位で selector や operation が切られるわけではないので、保守難易度は高そうです。
container 側では dispatch を叩かないとか、selector を挟まない、くらい厳しいルールを敷かないと、すぐにぐっちゃぐちゃになりそうですね。
useSelector 禁止、引いては container は store にアクセスしない、くらいは敷いても良さそうな印象を受けましたが、どうなんですかね。
ぶっちゃけドキュメントが 3 年前で更新が終わっているので、hooks の考慮はかなり弱そうです。
あと、index で types を export するケースはあまり好ましい状態ではないと思いますので、これはしぶしぶな措置なんですかね?
各 duck を切る粒度が難しそうですが、迷うくらいなら api ごとに 1 本切る、くらい細かく切っても悪くはなさそうです。
決して container 単位とか、適当とか、そういった粒度で切るものではないと思いますので、注意をば。
ducks パターンって結構難しくて、小規模なプロジェクトなら全然大丈夫なんですが、プロジェクトが大きくなってきたり、ducks を理解していないメンバーが好き勝手に書くとすぐに崩れます。
re-ducks でも根本の部分は ducks と同じで、duck をどういった粒度で切るのか、そもそも re-ducks の目的を理解できているのか。
そこがわからなければ、おとなしく元の redux のパターンで書くべきだよなーと思った、今日このごろです。