Reduxのアーキテクチャパターンの話
前提
アーキテクチャパターンとかなにがしたいのか
長期的に拡張、メンテができるアプリケーションを作る
属人性の高いものにはしたくない
Redux以前にあった問題
Controller→Model→Viewの一方通行のモデル
入力、データ処理、出力を分けることが目的
こうすることでViewなどはデータの永続化メカニズムを気にしなくて良くなる
複雑になりやすくスケールしない
Fluxが登場する前には流行っていたGUIのアーキテクチャパターン
Model, View, ViewModelの3つのコンポーネントからなる
ModelとViewの密結合を解決した
ViewModelがModelとViewのやり取りをする
規模が大きくなっていくと肥大化するのはViewModel
ViewModelはView側からくるユーザーのアクションも受け取らないといけないし、
Model側からくるfetchして来たデータなどを受け取らないといけない
そしてそれらをやり取りする
View↔VM、VM↔Modelの関係は一対一というわけではない
なので、一つのViewを修正したときに、複数のViewModelを変更しないといけない
同様に、一つのModelを修正したときも、複数のViewModelを変更しないといけない
つまりこれらは多対多の関係になる
あるViewModelがどのデータと依存しているのかを把握していないといけない
ちなみにmrsekut.iconは、調べたことがあるだけで実際に触ったことはないので知見は薄い
2014年のF8で発表された
結合関係を単一にする
多対多からの脱却
依存関係もシンプルになった
データフローが一方通行
つまり、データフローや、データを更新する場所に制限を設けた
Action、Dipathcer、Store、Viewの4つのコンポーネントからなる
Reactの各コンポーネントは状態を持たない
あくまでもアーキテクチャパターンなので実装は伴わない
Fluxフレームワークが大量に誕生した
Fluxは複数のStoreを持つ
Stateはmutateである
Fluxの問題点
参考
Reduxの原則
Single source of truth
State is read-only
Changes are made with pure function
Reduxが影響を受けたもの
参考
dispatcherからactionを分離した ?
Storeの役割をStoreとReducerに分離した
ReducerはActionを受け取りデータを更新(Write)
ReduxのStoreは最新のStateをViewに渡す(Read)
何かしらのデータを更新するときに、他のデータのことを考えないで良い
Stateを一枚岩にしてimmutableにStoreで管理するようにした
複数のStoreを持つFluxより厳しい制限
mutableなStateを持つFluxより厳しい制限
StoreはOmと同様にImmutableなので、どの状態が最新なのかが明確になる データの中のこの部分が古くて、この部分が新しい、のが混ざっちゃった、みたいなことが起こらない
タイムトラベルができる
デバッグにも役立つ
本番環境のredux devtool上で動くログツール
バグレポートの収集時などにユーザーの行ったactionを全て取得できるのでバグの再現ができる(はず
副作用が交じる部分を一箇所に追いやった
actionもreducerも参照透過な純粋関数
middlewareでのみ副作用が起こる
IOなど
結果として全てのコンポーネントをPureにできる
ローカルstateを使わずに、全てのstateをreduxで管理した場合。
Presentationは言うまでもなく、Containerもpure
Fluxと同じ一方通行のデータフロー
予測可能な形でコードを構造化する
Reduxはリーダビリティに重きをおいているので記述量が増えるのはしょうがない
代わりに読んだときに理解しやすい
関数型でないJSでやってるのが記述量が増える原因でもある
actionCreatorは返り値を取らない
Ationがコマンドモデル、更新系
Selectorがクエリ、参照系
宣言的に書くことができる
ViewとRedux側の依存が小さくなる
どのように?
propもstateも同じインターフェースで扱える
「stateの変更だから、this.state()を使うのか〜」みたいなことを考えたくない
参考
Reduxが解決したこと
「複雑さの根源は、変化と非同期性が混交していること」
Reactの話
Reduxの話
思ったこと
副作用をどう扱うか、というのがソフトウェア全体に蔓延る問題なんやなぁmrsekut.icon
参考