Savkin先生の記事を雑にメモする。これらの記事はngrx/storeを使う方法に誘導する感じがあるが、先生がまとめる問題点と解決策を整理してなんとかngrxよりも軽量でAngularにあった状態管理の方法を考えたい動機
(なのでReduxについての記述は飛ばしがち)
Managing State in Angular Applications
複数のバックエンドにあるサーバー、WebWorker、UIコンポーネントが並行して状態を更新するので、状態の管理は難しい。
何をメモリに、URLに保持すべきか?UIコンポーネントがローカルに保持すべきものは?これらの状態を同期するにはどうしたら良いか?
この記事では状態を6つに分類し、一般的な間違いとそれに変わるパターンを紹介する。
Types of State
- Server state
- Persistent state
- URL, router state
- Client state
- Transient client state
- Local UI state
Server state
サーバーで保持される状態。REST APIなどで提供される。
Persistent state
Server stateをクライアントサイドのメモリに保持したもの。Server stateのキャッシュと捉えることができる。実際はより良いUXのために楽観的更新がされる。
Client state
Client stateはサーバーに保存されない。リストをフィルタする設定がいい例になる。リストのアイテム自体はサーバーが保存しているが、それをフィルタする設定はそうではない。
Persistent stateと Client stateの両方をURLに反映するのはいいプラクティス
(It’s a good practice to reflect both the persistent and client state in the URL.) (Persistent stateもURLに反映する??)
Transient client state
URLには反映されないクライアントに保存される状態がよくある。例えば、Youtubeは再生している時間を保存していて、次に再生するときはそこから再生が始まる。この情報はURLに反映されないので、誰かにそのリンクを送るとその人は最初から動画を再生する。これがTransient client stateとなる。
Local UI state
ボタンの色や、メニューが展開されているかどうかがLocal UI stateにあたる。
状態の種類を決めるときは、それが共有されるかと、ライフタイムについて着目する
State Synchronization
Persistent stateとServer stateはは同じ情報を保持する。Client stateとURLも同様。なのでこれらを同期する必要がある。
...普通の実装をしてSavkin先生がツッコミを入れる図
Mistakes
- 状態を計算するところとサービスから、状態の管理を分離しなかった
- Persistent stateとServer stateを同期する戦略を明確にしていなかった
- Client stateとURLを同期する戦略を明確にしていなかった
- モデルがmutableだった
Refactoring 1: 状態管理の分離
- 分離
- サービス
- 状態管理
- Redux
- Redux自体がゴールではない
- 非Local stateを1箇所で管理する
- Immutable data
Rule 1: 状態の管理をアプリケーションの残りの部分と分離する
Rule 2: 楽観的更新はエラーに対処するために分離したアクションを必要とする
Rule 3: Persistent stateとClient stateにはImmutable dataを使う
Rule 4: Reduxは目的を達成するためのものであり、それ自体が目的ではない
Refactoring 2: Routerと状態
- Router is the source of truth
- Persistent stateとClient stateを管理するが、Client stateは管理しない
- アクションを発行する
Rule 5: 常にRouterをsource of truthとして扱う