今回は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),
),
),
),
);
}
}
以上です。