しばらく前からReact.jsは使っていたのですが、この度本格的なSPAアーキテクチャのアプリを作るに当たって、rebuildでちらっと耳にしたReduxを使ってみることにしました。
Fluxのコンセプトを継承しつつも各クラスの役割分担がちょっと違うので、個人的なメモをここに書きためておきます。
Flux
Fluxのアーキテクチャは以下のようなものだと理解しています
- ユーザの操作によってActionCreaterを実行する
- ActionCreaterは必要に応じてサーバにリクエストを送ったりして、Actionオブジェクトを作りDispatherに渡す
- Dispacherは全てのStoreにActionを通知する
- Storeは関心のあるActionであればデータの更新処理などを行ってから関連するViewに更新イベントを通知する
- Viewは更新イベントを受けとるとStoreから最新のデータを取得して、自身のstateを変更して再描画を行う
Redux
で、これがReduxになるとこう
- ユーザの操作によって処理を実行するためのコールバックメソッドを呼び出す
- コールバックメソッド内でActionCreaterを呼び出し、その結果のActionを引数にStoreのdispatchを呼び出す
- StoreからReducerにActionが渡され、Reducerは関心のあるActionであればそれに応じた新しいstateを返却する
- stateを元に新しいpropsがViewに伝播されて再描画が行われる
違い
違いとしてはこんなところでしょうか
- Fluxでは複数のStoreが独自にデータを保持するが、Reduxでは単一のStoreがReact.jsのstateで全てのデータを保持する
- FluxではViewからActionCreaterを呼び出しているけれど、ReduxではActionCreaterを実行してdispatchを呼び出すコールバックメソッドをprops経由で受けとって実行する
- FluxではStoreが自身のデータを変更するメソッドを持つが、ReduxではActionと現在のstateを受けとって新しいstateを返すReducerがそれの代わりとなる
- Fluxでは描画を行うコンポーネントがStoreから直接データを取得しているが、Reduxではデータは全て親からprops経由でもたらされる
所感
ReduxはFluxのコンセプトをより洗練された形で実装できる印象です。
オリジナルのFluxも実際に使ったことはないので実感を伴った感想はありませんが、描画コンポーネントがpropsを元に描画するシンプルな実装になるのは歓迎できますし、データが独自のStoreで個別に管理されるのではなく global state で管理されるというのも納得できる気がします。