torikatsu923.dev

サイト内検索

    riverpod_generatorを使ってみる

    2022/11/20追記: スニペットに間違いがあったため修正しましたriverpod関連のパッケージにriverpodgeneratorというものがあります。

    2022/11/20追記: スニペットに間違いがあったため修正しました

    こんにちは、とりかつ@torikatsu923です。

    riverpod関連のパッケージにriverpod_generatorというものがあります。
    これはアノテーションをつけるだけで各providerを生成してくれるとても便利なツールです。

    riverpod_generator | Dart Package

    今までStateNotifierProviderを宣言する際は次のようにしていましたが、

    final someNotifierProvider = StateNotifierProvider.autoDispose<SomeNotifier, String>((ref) => SomeNotifier());
    
    class SomeNotifier extends StateNotifier<String> {
      // ...
    }

    これだけでよくなります。最高ですね!

    @riverpod
    class SomeNotifier extends StateNotifier<String> {
      // ...
    }

    今回の記事ではriverpod_generatorのセットアップと、各providerの生成方法を紹介します。

    セットアップ

    1. 依存関係の追加

    次のようにriverpod, riverpod_annotationをdependenciesに、build_runnerとriverpod_generatorをdev_dependenciesへ追加し、flutter pub get します。

    dependencies:
      riverpod:
      riverpod_annotation:
    
    dev_dependencies:
      build_runner:
      riverpod_generator:

    2. コードを自動生成

    次のコマンドをターミナルで実行し、providerを自動生成します。

    dart pub run build_runner build

    watchを実行するとコードの変更を検知してその都度buildを走らせてくれます

    dart pub run build_runner watch

    tips

    コマンドを実行すると、対象のファイルと同じディレクトリ階層に xxx.g.dart というファイルが生成されます。プロジェクトの規模が大きくなるにつれて、自動生成されたファイルの数が多くなりノイズになっていきます。

    build.yamlへ以下の設定を記述しておくと、自動生成ファイルの生成先ディレクトリを指定することができる様になりファイルがスッキリします。

    build.yaml

    targets:
      $default:
        sources:
          - $package$
          - lib/**
          - stories/**
        builders:
          source_gen|combining_builder:
            options:
              build_extensions:
                '^lib/{{}}.dart': 'lib/generated/{{}}.g.dart' # コロンより右側が生成先を指定している。
          riverpod_generator:
            options:

    上の例ではlib/generated配下にファイルが生成される様になっています。

    ↓↓参考↓↓

    【Flutter】freezed・json_serializableのファイル生成先を変更するためのbuild.yaml - torikatsu.dev

    各Providerの生成方法

    // 普通のProvider
    @riverpod
    String someValue(_) => 'some value';
    
    // 今まで通りscopedProvider用にUnimplementedErrorをthrowする方法も使えます
    @riverpod
    String someScopedValue(_) => throw UnimplementedError();
    
    // FutureProvider
    @riverpod
    Future futureValue(_) async => 'future value';
    
    // AsyncNotifierProvider.autoDispose
    @riverpod
    class SomeAutodisposeAsyncNotifier extends AutoDisposeAsyncNotifier<String> {
      @override
      FutureOr<String> build() {
        throw UnimplementedError();
      }
    }
    
    // AsyncNotifierProvider
    @Riverpod(keepAlive: true)
    class SomeKeepAliveAsyncNotifier extends AsyncNotifier {
      @override
      FutureOr build() {
        throw UnimplementedError();
      }
    }
    
    // StateNotifierProvider
    @riverpod
    class SomeAutodisposeStateNotifier extends AutoDisposeNotifier<int> {
      SomeAutodisposeStateNotifier();
    
      @override
      int build() {
        return 0;
      }
    }
    
    // StateNotifierProvider.autoDispose
    @Riverpod(keepAlive: true)
    class SomeKeepAliveStateNotifier extends Notifier<int> {
      SomeKeepAliveStateNotifier();
    
      @override
      int build() {
        return 0;
      }
    }

    おわりに

    riverpod_generatorはriverpodの作者さんのリポジトリに属するパッケージのため、今後も安心して使えるパッケージとなっています。 providerの宣言が面倒と感じるようになったらぜひ試してみてください。

    -––