今回は初めて記事を書くことになりますが、よろしくおねがいします。私はiOSエンジニア(Swift)をやっていました。2ヶ月前あたりにはちょうどiOSとAndroid両方対応しないといけないプロジェクトを始めたのでいろいろを検討をしていました。最初はReact Nativeを検討していましたが、Expoがすごくよかったと思いますが、やっぱり自分はJSとフロントエンド開発には向いていないと思いますので、Nativeで両方iOSとAndroidを別々でやろうと思いました。TypeScriptをReact Nativeプロジェクトに入れようとしてもいろいろいじらないといけないのでめんどくさいなと思っていましいた。その時、ちょうど友人がちょっとFlutterをやってておすすめされました。Flutterをインストールして、VSCodeのPluginもよくできているので、FlutterとDart(言語的に)好きになりました。今回はタイトルと違ってFlutterでReduxを使った感想を書きます。ReactNativeとかとは比較しません(笑)。
Reduxとは?
私も最近までReduxを理解したばかりなので、おそらく私より説明できる記事はいくらでもあると思います。そちらの参考をおすすめします。今回は私が理解しているイメージを書きます(もし間違ったらコメントをいただければ助かります)。Flutterは各StatefulWidget
は自分のデーターは自分で管理しています。Widget内のデーターの操作ももちろん、他のWidgetにデータを受け渡すや操作などはいろいろやっています。以下のようだいたいカオスになりやすいと思います。
Reduxの場合だとデーターの操作は一方通行になるので、綺麗になります。
データーと画面の状態(state)は全部Storeの中に入っています。そこでWidgetがStateを更新したい場合(ボタン押したらラベルが変わるなど)はActionをReducerにdispatchします。Reducerが現在のStateとActionを受け取って新しいStateを作成する。それが終わったら、Widget達がStoreのStateを参考して画面を更新するというフローになっているかと思います。
なぜFlutterでReduxを使う?
ReduxはReactのUIのStateを管理する人気なフレームワークですがRedux自体はただの考え方なので、どこでも応用できます。SwiftだったらReSwiftでもちろんFlutterもflutter_redux
というのもあります。下は私がReduxを使っていいと思ったことをリストアップします。
1. 全てのWidgetsはStatelessWidgetになると
普通に`StatefulWidget`を実装する場合は画面を作成時にはWidgetの中のデーターを参考して作成しますが、`flutter_redux`の場合はデーターは全部`Store`内に管理しますので、2. ロジックとビューの部分を完全分ける
普通にStatefulWidgetを使う場合
普通のStatefulWidgetの場合はデーター、ビュー、ロジックは全部 `State`のクラスに書くのでコードが煩雑になりやすいです。分ける方法は別でいろいろあると思いますが([MVVMとか](https://medium.com/flutter-community/easily-navigate-through-your-flutter-code-by-separating-view-and-view-model-240026191106))。flutter_reduxの場合
`flutter_redux`を使う場合は`StatefulWidget`が`StatelessWidget`になって、データーは全部 `Store`に入れます。データーを操作したい時は`Action`をdispatchして、`Reducer`内でロジックを実装することになるのでかなり綺麗になります。3. Redux Time Travelを前のStateに戻る
Redux Time Travelを使って前の状態とかに戻してDebugできます。
4. UIテストするのは簡単
私はまだUIテストはそんなにやっていませんので詳しくは言えませんが、Statesを作成して、画面ごとに渡せばUIテストはしやすいだと思います(ロジックとビューがちゃんと分けているので)。
flutter_redux
デメリット
これはflutter_redux
の問題だけではなくて、基本Reduxの問題だと思いますが、かなりめんどくさいです。簡単なものをやりたいだけなのに、States, Actions, Reducersなどを作らないといけないのでファイル数が多くなりやすいです(ファイルを分ける場合)。
よく使う flutter_redux
の機能(Cheat Sheet)
私は記憶がよくないので、必要な時は毎回検索しないといけないので、一応はよく使われているものをメモをしてますので以下にリストアップします。
WidgetをStoreに接続する
StoreConnector<AppState, ViewModel>(
converter: (AppState store) => viewModel,
builder: (BuildContext context, ViewModel viewModel) {
return Text(viewMode.someRandomText)
},
)
これを使ったら、このStoreConnector
の下のWidgetsはstoreの状態を取れるようになります。Storeのdispatch
も呼べるようになります。あとは ViewModel
が変更されたら、build()
が再起動されます。
ActionをDispatchする
StoreProvider.of<AppState>(context).dispatch(MyRandomAction(value: 'Hello'));
これを使えばcontext
内のどこでもActionを楽々dispatchできます。
Storeの中のStateを取ってくる
final state = StoreProvider.of<AppState>(context).state;
final randomValue = state.myRandomValue
StoreConnector
以外にもこれを使えば状態を取れます。
まとめ
私的にはReactNativeをやった頃よりはReduxを好きになりました。最初の設定はかなりめんどくさい(State追加とかも)ですが最初からディレクトリを設計することでアプリの構成が綺麗になるかと思います。今回はMiddlewareまでは書く時間はなかったので、また時間を見つけて書きたいと思います。あとは他のFlutterのパターンも勉強してReduxを比較にしたいと考えております。