Flutterアプリ開発

Riverpodの仕組みと使い方について解説

Riverpodとは?

Flutterで利用できる状態管理ライブラリの1つです。Flutterのライブラリの中でもよく使われており人気のあるライブラリです。Dartのみでも利用することができます。ちなみに、RiverpodはProviderのアナグラムになっています。

状態管理とは?

FlutterではデータやUIの状態をState機能を利用して管理しています。Riverpodではこの状態の管理や利用しやすくしてくれています。

主な構成要素

Riverpodで重要な役割を持つ以下の4つのことについてざっくり紹介します。

  • プロバイダ
  • ref (参照)
  • Observer
  • Scopes

Providers (プロパイダ)

プロパイダは、ステート(状態)を保管し監視することを可能にするオブジェクトです。ステートに変更があった時に通知してくれます。

final userProvider = FutureProvider.autoDispose.family<User, int>((ref, userId) async {
  return fetchUser(userId);
});

ref (参照)

refはプロパイダの機能を利用するときに使うオブジェクトです。refを通じてプロパイダへアクセスすることができます。

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

  void increment() {
    // Counter can use the "ref" to read other providers
    final repository = ref.read(userProvider);
    userProvider.get('...');
  }
}

ProviderScope (スコープ)

プロバイダーを管理するための空間を作ります。プロバイダーはこの空間で存在することができます。

@riverpod
String helloWorld(HelloWorldRef ref) {
    return 'Hello world';
}

void main() {
    runApp(
        // ProviderScope を置くことで Riverpod が有効になる
        ProviderScope(child: MyApp(),),
    );
}

class MyApp extends HookConsumerWidget {
    @override
    Widget build(BuildContext context, WidgetRef ref) {
        final counter = useState(0);
        final String value = ref.watch(helloWorldProvider);
        // ...
    }
}

ProviderObserver (オブザーバー)

同一スコープ内にあるプロバイダーの変更を検知することができる。下記の例は、オブザーバーでカウンターの値の変更を検知し、ログとして出力している。

class Logger extends ProviderObserver {
  @override
  void didUpdateProvider(
    ProviderBase<Object?> provider,
    Object? previousValue,
    Object? newValue,
    ProviderContainer container,
  ) {
    print('''
{
  "provider": "${provider.name ?? provider.runtimeType}",
  "newValue": "$newValue"
}''');
  }
}

void main() {
  runApp(
    // Logger インスタンスを observers のリストに追加する
    ProviderScope(observers: [Logger()], child: const MyApp()),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: Home());
  }
}

final counterProvider = StateProvider((ref) => 0, name: 'counter');

class Home extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);
    // ボタン押下時などに、変更処理を加えるとオブザーバーで検知される
  }
}

Providerとの違い

ProviderはRiverpod内で使われているコアパッケージの一つです。Providerで提供されている機能を、コード生成や特定の条件下で使いやすくしたものがRiverpodになります。

riverpod generatorとは?

Riverpodでは、アノテーションを利用することでプロバイダやオブザーバーの定義などを自動生成してくれるgeneratorという仕組みがあります。

仕組み

基本は、Providerの仕組みと同じでプロバイダで管理している値に変更があったら、各UIなどにBuildContextを通じて変更を通知する仕組みになっています。

使う場面

ウィジェット内で管理する状態が多くなったり、変化するロジックが複雑になったり、複数ウィジェット間で同一の状態を管理する必要が出てきた場合に、そのためのロジックを切り出すために利用することが多いです。

パッケージのインストール方法

下記のコマンドを使ってインストールすることができます。

$ flutter pub add riverpod
$ flutter pub get

使用の際の注意点

Riverpodのreadやwatch, listenなどはFlutterやWidgetのライフサイクルを考慮して設計されています。そのため「ref.read は build メソッドの中で使用する」といったライフサイクルを破壊するような使用を避けることが必要になります。

ウェブサイトFlutterでウェブ表示するwebview_flutterの特徴とその使い方について解説!Prev

Related post

  1. Flutterアプリ開発

    Flutterで簡単なカウンターアプリを作ってみよう

    FlutterではさまざまなUIを実装するためめに、多くのパーツが用意…

  2. Flutterアプリ開発

    Flutterを使ったタスク管理アプリUIの作り方を解説

    Flutterを使ったアプリ開発について勉強してきたら、それらの知識を…

  3. Flutterアプリ開発

    Flutterで一覧表示の実装に使える3つの方法

    みなさんは様々なスマホアプリを日頃から触っていると思います。様々なアプ…

  4. ウェブサイト

    Flutterアプリ開発

    Flutterでウェブ表示するwebview_flutterの特徴とその使い方について解説!

    Flutterでアプリ開発をしているとウェブ表示をしたいという要望が出…

  5. Flutterアプリ開発

    初めてでも開発できるFlutter入門

    FlutterでAndroidやiPhoneアプリを作りたいけれど、ど…

  6. dart

    Flutterアプリ開発

    Dartの基本的な書き方やFlutterで活用する方法を紹介

    Flutterを使ったアプリ開発では、Dart言語というプログラミング…

PAGE TOP