JINMUSOFTWARE

Riverpod 3 入門 ~FutureProvider~

FutureProviderに挑戦してみましょう。

参考

環境

  • flutter_riverpod 3.2.0
  • flutter 3.38.6

Install

flutter_riverpodのパッケージをinstallします。

Bash
flutter pub add flutter_riverpod

Version 3.2.0 がインストールされました。

次にlintの設定もしておきましょう。

analysis_options.yaml
plugins:
  riverpod_lint: ^3.2.0

上記だけでいいみたいですね。

FutureProvider

ではFutureProviderの簡単なコードを書いていきましょう。

FutureProviderは非同期処理を記述することができます。

数秒待機して、日付時刻を返す処理を記述してみます。

ファイル名:time_provider.dart

time_provider.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';

// FutureProviderです。
// async付いていますよ。
final timeProvider = FutureProvider<DateTime>((ref) async {
  await Future.delayed(const Duration(seconds: 1));
  return DateTime.now();
});

次にproviderをwatchして表示する部分を作ります。

main.dartにはいつものimportとProviderScopeを追加します。

main.dart
// import追加
import 'package:flutter_riverpod/flutter_riverpod.dart';

// ProviderScope設置
void main() {
  runApp(const ProviderScope(child: MyApp()));
}

ConsumerWidgetを継承したWidgetを作成します。

さて、FutureProviderが提供する値の型は、「AsyncValue<T>」型です。

AsyncValue<T>型には3つの状態があります。

「.when」か「switch式」で切り分けます。

main.dart
// ConsumerWidget継承
class Page1 extends ConsumerWidget {
  const Page1({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    //
    // watchします。
    final timeAsyncValue = ref.watch(timeProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('Page 1')),
      body: Center(
        child: Column(
          children: [
            //
            // whenを使用するversion
            timeAsyncValue.when(
              data: (dateTime) => Text('Current Time: $dateTime'),
              loading: () => CircularProgressIndicator(),
              error: (error, stack) => Text('Error: $error'),
            ),

            //
            // switch式
            switch (timeAsyncValue) {
              AsyncData(:final value) => Text('Current Time: $value'),
              AsyncLoading() => const CircularProgressIndicator(),
              AsyncError(:final error) => Text('Error: $error'),
            },
          ],
        ),
      ),
    );
  }
}

実行画面です。日付時刻が表示されましたね。

code
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'time_provider.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(colorScheme: .fromSeed(seedColor: Colors.deepPurple)),
      home: const Page1(),
    );
  }
}

class Page1 extends ConsumerWidget {
  const Page1({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    //
    final timeAsyncValue = ref.watch(timeProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('FutureProvider Demo')),
      body: Center(
        child: Column(
          children: [
            const SizedBox(height: 20),
            //
            // timeAsyncValueの状態に応じてUIを変える
            // whenを使用するversion
            timeAsyncValue.when(
              data: (dateTime) => Text('Current Time: $dateTime'),
              loading: () => const CircularProgressIndicator(),
              error: (error, stack) => Text('Error: $error'),
            ),
            //
            // Reloadボタン
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                ref.invalidate(timeProvider);
              },
              child: const Text('Reload'),
            ),
            //
          ],
        ),
      ),
    );
  }
}