概要
以前ReactNativeでイラスト閲覧アプリを作ったが、今回はそのままの仕様でFlutterで1から書き直した。
両方触ってみた結果、個人的にはFlutterの方が好みだったのだが、
どういった部分で魅力に感じたのか簡単にまとめようと思う。
ReactNativeは0.52.0とかそれくらいの時期に触ってた記憶のものなので、
もしかしたら改善されているかもしれない(期待感)
雑に箇条書き
記事をまとめる力が尽きる前にざっと箇条書きする。
まとめる気持ちが向いてきたら詳細に落としていく。
※以下個人の感想です
良い
- dartの言語は複雑ではないので取っ付きやすい。すぐ覚えられる。
- async/awaitあるのもいいね(jsにもあるから優位性はないけど)
- ViewはReactNative同様組みやすい
- CenterとかExpandedとかレイアウト用のWidgetがあって最初は慣れななかった
- 慣れてしまえばサクサク作れる
- ReactNativeに比べてFlutterのバージョン上げやすい
-
flutter upgradeの後、特にすることがない -
react-native-git-upgradeの後の悲しいコンフリクト解消みたいなのは自分の環境では今のとこ無さそう
-
- Android Studioと組み合わせると開発が便利
- 保存時に自動的に依存解決してくれる
- 保存時に自動的にホットリロードしてくれる
- エミュレータ起動用のUIがあるのですぐ起動できる(iOS/Android両方)
- 慣れ親しんだショートカットキーが使える(これは人による)
- プロジェクト作成時にオプション付ければネイティブのコードを
swift/kotlinで作成してくれる- ReactNativeだと
Java/Objective-Cがデフォだった
- ReactNativeだと
- ネイティブライブラリに依存したプラグイン入れても自動的にリンクしてくれる
- pubspec.yamlに書いて保存したらもう参照できるようになってた。意識しなくていいレベル。
-
react-native linkより楽(ライブラリによっては非推奨なこともあるし)
- 自作プラグインのプロジェクト作成時に
exampleもセットで作成してくれるのは嬉しい- 作ったウィジェットやモジュールをすぐ試せる
- ReactNativeは自分で作る必要があった
- ネイティブのViewとの繋ぎこみの
過程はどっちもどっち- プロジェクト作成時点で
kotlin/swiftが用意されてるからその分楽と言えば楽か
- プロジェクト作成時点で
- 複雑なリストを組む仕組みが標準で用意されている
- CustomScrollView + Sliverを使う
- 考え方が自分の作ったrecyclerview-adaptersに近くて好み
- データバインディング用のWidgetやクラスが用意されてる
-
StreamやStreamBuilderあたりを使うと値がある状態を保証して表示とかが書きやすい - RxDartのBehaviorSubjectも使えば困ることは無かった
-
- アノテーションからコード自動生成みたいな仕組みがある
- Android(というかJava)でよく使われているAnnotation Processingと同じような感じで色々できそう
- json_serializableはアノテーションからJSONシリアライズ・デシリアライズの処理を自動生成してくれる
不満
- 普段kotlinとかswiftとか書いてるとdartが物足りなく感じる
- enumがシンプルすぎる...
- 拡張関数使いたい(mixinがあるので大体は解消できる)
- セミコロンがもはやだるい
- importしてないクラスはクラス名全部打ってからじゃないと補完してくれない
- これはAndroid Studioのプラグインへの不満
- せめて自分のプロジェクト内で作ったクラスくらいは2文字くらい打ったら補完してほしい
- ライブラリ少ないなぁ
- 検索しても関係ないやつばかり引っかかってくる
- 自分も作ってく内にどんどんpackage切り出して貢献していく気持ち
その他
- AndroidやiOSの知識不要かと言われるとそんなことはない
- 特にリリースビルドはそれぞれの知識が少なからず必要になる
- ここら辺は仕方ない
解せぬ
以下のコード実行時エラーになる(コンパイルは通る)
環境構築だるい人はDartPadで試すとわかる(https://dartpad.dartlang.org/)
void main() {
final piyo = [1, 2, 3, 4, 5];
final stringPiyo = piyo.map((value) => value.toString());
/// Uncaught exception:
/// TypeError: Instance of 'MappedListIterable<int, String>': type 'MappedListIterable<int, String>' is not a subtype of type 'List<String>'
Hoge(values: stringPiyo);
}
class Hoge {
List<String> values;
Hoge({this.values});
}
これは最後にtoList()を加える必要がある。
final piyo = [1, 2, 3, 4, 5]; // List<int>
final stringPiyo = piyo.map((value) => value.toString()).toList(); // toList無しでもList<String>になってくれよお