Udemyセール開催中! 対象コースが1,220円から

【Flutter×Riverpod】FutureProviderの使い方|プロバイダで状態管理

今回はRiverpodのプロバイダ「FutureProvider」をFlutterで使用する方法を紹介します。

FlutterでRiverpodを使うのが初めての方は先にこちらの記事をお読みください。

目次

Riverpodの導入

$ flutter pub add flutter_riverpod
$ flutter pub get

pubspec.yamlにパッケージを追加・更新

import 'package:flutter_riverpod/flutter_riverpod.dart';

main.dartファイルにコピペ

「ProviderScope」をFlutterアプリのルートにする

void main() {
  runApp(ProviderScope(child: MyApp()));
}

「ProviderScope」をrunApp()でFlutterアプリのルートにします。これでFlutterアプリでRiverpodのプロバイダを使えるようになりました。

「FutureProvider」の使い方

コードで解説してる箇所は記事下のサンプルコードを参考にして読んでみてください。

概要

FutureProviderを使えば非同期処理(Future型)が必要なデータを取得できます。

定義

//定義
final プロバイダ名 = FutureProvider<型>((ref) async {
  await 非同期処理...;
  return 返り値;
});

//例
final futureProvider = FutureProvider<String>((ref) async {
  await Future.delayed(Duration(seconds: 3));
  return 'Hello World';
});

上記コードのように定義します。

「ref」をWidgetで使用可能にする

プロバイダの値を取得するには「ref」を使用します。ただ通常のStatelessWidget、StatefulWidgetでは「ref」を使用できないので下記のように置き換える必要があります。

StatelessWidgetでプロバイダを使用する場合

class MyApp extends ConsumerWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Container();
  }
}

「StatelessWidget」を「ConsumerWidget」に置き換える必要があります。またbuild()の第二引数に「WidgetRef ref」を渡します。Riverpodのコードスニペットプラグインを入れておけば自動生成できます。

StatelessWidgetでプロバイダを使用する場合

class MyApp extends ConsumerStatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  ConsumerState<ConsumerStatefulWidget> createState() => _MyAppState();
}

class _MyAppState extends ConsumerState<MyApp> {

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

「StatefulWidget と State」を「ConsumerStatefulWidget と ConsumerState」に置き換える必要があります。StatelessWidget同様コードスニペットで自動生成できます。

ref.watchでプロバイダからデータを取得

final future = ref.watch(futureProvider);

//下記の方法もOK
AsyncValue<String> future = ref.watch(futureProvider); 

上記コードのように「ref.watch」でプロバイダのデータを取得します。

whenメソッドで非同期処理のステート別に処理を指定

//例
future.when(
  loading: () => const CircularProgressIndicator(),
  error: (err, stack) => Text('Error: $err'),
  data: (data) => Text(data),
),
  • loading:処理中
  • error:エラー
  • data:取得成功

FutureProviderからデータを取得する際、非同期処理のステート(状態)別に実行する処理を決める必要があります。

サンプルコード

DartPadを実行すると、非同期処理中の5秒間(Future.delayed)はloadingプロパティのコールバック関数で指定したCircularProgressIndicator()が実行され、データの取得が成功するとdataプロパティで指定した処理が実行されます。

//ソース
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final futureProvider = FutureProvider<String>((ref) async {
  await Future.delayed(Duration(seconds: 5));
  return 'Hello World';
});

void main() {
  runApp(
    ProviderScope(child: MyApp()),
  );
}

class MyApp extends ConsumerWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final future = ref.watch(futureProvider);

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Riverpod'),
        ),
        body: Center(
          child: future.when(
            loading: () => const CircularProgressIndicator(),
            error: (err, stack) => Text('Error: $err'),
            data: (data) => Text(data),
          ),
        ),
      ),
    );
  }
}

以上です。

参考

Riverpod:FutureProvider

  • URLをコピーしました!
目次
閉じる