😯

【Flutter】初心者がRiverpod 2.0を使ってみた

2024/12/15に公開

初めに

自己紹介

こんにちは!ミーハーコーダーのさるしぃです。今まではPythonをメインで触ってきて、インターン先ではKotlin+Jetpack Composeを主に使ってAndroidアプリを作っています。
来年から友人のスタートアップを手伝うかもしれないという超絶おもろい展開なので、MVP最速で作れるFlutterを勉強しています。
インターン先ではMVVM+Clean Architectureみたいな独特なアーキテクチャを使っていますが、今回はMVVMをどう実装できるかについてまとめてみます

Requirements

pubspec.yamlに以下の内容を追加してください

pubspec.yaml
dependencies:
  flutter_riverpod: ^2.6.1
  riverpod_annotation: ^2.6.1
dev_dependencies:
  build_runner: ^2.4.13
  riverpod_generator: ^2.6.3

Riverpod2.0の変更点

StateNotifier is Deprecated

僕がプログラミングで大っ嫌いな言葉ランキング1位のDeprecatedが出てきました。今まではStateNotifierを使って次のようなコードを書くことが多かったそうです。

before.dart
// 状態管理クラス
class CounterNotifier extends StateNotifier<int> {
  CounterNotifier() : super(0); // 初期値を0に設定

  // 状態を変更するメソッド
  void increment() {
    state++; // 状態を更新
  }
}

// プロバイダの定義
final counterProvider = StateNotifierProvider<CounterNotifier, int>(
  (ref) => CounterNotifier(),
);

MVVMではStateNotifierとプロバイダの定義は別々…とかはいったん置いといて進めます。ようはいままでStateNotifierっていうのを継承してその初期値をsuper()コンストラクタで決めよう的な感じです。
最初これで自分はrefで躓いたんですよねぇ…そもそもプロバイダも全部StateNotifierの中で定義してくれたら別でわざわざプロバイダを定義してrefを参照する必要ないのにって。

Notifierを使ってみよう

これをNotifierを用いて書くと。。。

after.dart
part of 'counter.g.dart';

class Counter extends _$Counter {
  
  int build() => 0;

  void increment() {
  }
}

ちなみにこれではエラーを吐くのでアプリのルートディレクトリで以下のコマンドを実行してください

$ flutter pub run build_runner build

そうすると次のようなファイルが出来上がると思います(一例)

counter.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'counter.dart';

String _$counterHash() => r'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // ハッシュ値

/// See also [Counter].
(Counter)
final counterProvider =
    AutoDisposeNotifierProvider<Counter, int>.internal(
  Counter.new,
  name: r'counterProvider',
  debugGetCreateSourceHash:
      const bool.fromEnvironment('dart.vm.product') ? null : _$counterHash,
  dependencies: null,
  allTransitiveDependencies: null,
);

typedef _$Counter = AutoDisposeNotifier<int>;

中身を見ると予測できるようにcounterProviderが内部で生成されているんですよね
これは超絶便利

他の要素について

他の要素は初心者の自分からしたらよく分かりませんでした。(非同期処理周りは確かに楽になりそう)
ただ、数多くのProviderがある中で一本化しようとする動きがあるのは自分としては使いやすくなるので嬉しいですね
あと、実際にViewとかで使うときにref.watchするのとかは大きく変化ないです!ありがたい!

ぜひ見て下さい

最後まで読んでくださってありがとうございます。簡易的なMVVMを用いて作ったTodoアプリがあるのでもしよければそちらも見てください(クオリティは低いです)
また、内容の方間違っている可能性はあるかもしれないので何かありましたら言っていただけると大変助かります!
https://github.com/sarushili0430/flutter_todolist

Discussion