Pinia などのフロントエンドの状態管理の文脈で言われるストアとはユースケースとかアプリケーション層なのではないか
状態管理ストアはだいたいが Flux の影響を受けていそう
Flux では Action, Dispatcher と Store が別だが、最近の状態管理ストアの実装はこの辺が全部まとまってる
最近は Action と Dispatcher の境目がない
ここが分かれているのは Action を serializable なデータにして、Dev tool とか logger で呼ばれた Action を追跡できるようにするためだったが、ツールの発達により必要なくなった
今は Action というと実際に処理が書かれた関数を指す
Flux では Store にドメインロジックを書くとされているが、Flux に影響を受けたライブラリはみんな Store もライブラリの中に入れていて、ドメインロジックを書くのに適していない
ドメインロジックは依存されることはあっても依存するべきではないとされている
ライブラリを使ってドメインロジックを書いたら、そのドメインロジックはライブラリに依存している
だからこそこの辺をすべてカバーしようとするライブラリは少なくなってきて、もっと小さい機能だけを持つライブラリが増えてきたのかも
なにも考えずに書くとストアという名前からリポジトリっぽく書いてしまいがちだけど、そういうストアは後から結構つらくなる
例えば、ショッピングカートを実装する時
商品をカゴに入れるボタンを押した時
ストアの実装がリポジトリっぽく書かれていると
カゴに同一の商品がない時は addItem
同一の商品がある場合は updateItemCount
みたいな条件分岐を書き分ける必要がある
ストアの実装がユースケースっぽく書かれていると
View からは addItem だけ呼び出す
ストア内で同一の商品がある場合とない場合の処理を分ければ良い
View 側ではなにも考えずにユースケースに沿ったストアの関数を呼べば良い
ストアが CRUD だと View 側でアプリケーションのロジックを書く必要が出てくる
これを防ぐためユースケース層を独自に書くと、ストアとの取り回しが悪くなる
ストアのインスタンスは View に DI されていることが多い
SSR の都合で、直接 import が推奨されない
独自ユースケースからストアを呼ぶ時、そのストアは View から渡されるという歪なフローになりがち
ここを楽にするためにユースケースを composables (hooks) にしているケースも見たことあるが、View と混ざりがちなのでつらくなりそう
人間には、同じ見た目のものに対して異なる概念を使い分けることが難しい
とはいえ普通のアプリとか Web ページだとフロントエンドのロジックは薄いことが多いので、ユースケースとリポジトリを合体させたようなストアでもなんとかなったりする
バックエンドにロジックを逃したり
インタラクションが厚いアプリだとストアじゃなくてもっと View に近い方にインタラクション関連のロジックが盛られていく
そもそもストアがいらない説もある
React の Context で十分みたいな論は結構聞いた
これは結局ストアに相当するなにかを自分で設計する必要はありそうだが
設計の必要がないほど簡単なアプリならデータを Context で共有するだけでいいという話もありそう
結局バックエンドのデータを選択して表示するだけだから Apollo Client だけでいい説とか
Apollo Client 自体がキャッシュとそのキャッシュを更新する仕組みを持つので、すごく単純なストアと見ることもできる