👻
【Flutter】riverpod_generator 動作確認用コードサンプル
Riverpod の各プロバイダのサポート状況
「Riverpod の各プロバイダ」の 「riverpod_generator でのサポート状況」について、表にまとめます。2023/01/21 時点。
No. | プロバイダ | サポート状況 | 備考 |
---|---|---|---|
1 | Provider | サポート済 | |
2 | NotifierProvider | サポート済 | |
3 | AsyncNotifierProvider | サポート済 | |
4 | StateNotifierProvider | まだ未サポート? | (Async)NotifierProvider で代替? |
5 | FutureProvider | サポート済 | |
6 | StreamProvider | まだ未サポート? | サポート対応中? |
7 | StateProvider | サポートしない? | [1] |
8 | ChangeNotifierProvider | まだ未サポート? | (Async)NotifierProvider で代替? |
各プロバイダの動作確認用コードサンプル
Provider
Provider
test/riverpod_generator/provider_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'provider_test.g.dart';
String Function(String s) hello(HelloRef ref) {
String hello(String s) {
return "Hello World $s";
}
return hello;
}
String Function(String s) helloF(HelloRef ref, {required String init}) {
String hello(String s) {
return "$init $s";
}
return hello;
}
void main() {
group("basic", () {
test("Provider", () {
final container = ProviderContainer();
expect(helloProvider, isA<AutoDisposeProvider>());
final hello = container.read(helloProvider);
expect(hello("add"), "Hello World add");
});
});
group("family", () {
test("Provider", () {
final container = ProviderContainer();
expect(helloFProvider, isA<HelloFFamily>());
final hello = container.read(helloFProvider(init: "Hello World"));
expect(hello("add"), "Hello World add");
});
});
}
NotifierProvider
NotifierProvider
test/riverpod_generator/notifier_provider_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'notifier_provider_test.g.dart';
class HelloNotifier extends _$HelloNotifier {
String build() {
return "Hello World";
}
void add(String s) {
state = "$state $s";
}
}
class HelloNotifierF extends _$HelloNotifierF {
String build({required String init}) {
return init;
}
void add(String s) {
state = "$state $s";
}
}
void main() {
group("basic", () {
test("NotifierProvider build", () {
final container = ProviderContainer();
expect(helloNotifierProvider, isA<AutoDisposeNotifierProvider>());
expect(container.read(helloNotifierProvider), "Hello World");
});
test("NotifierProvider add", () {
final container = ProviderContainer();
expect(helloNotifierProvider, isA<AutoDisposeNotifierProvider>());
expect(container.read(helloNotifierProvider), "Hello World");
container.read(helloNotifierProvider.notifier).add("add");
expect(container.read(helloNotifierProvider), "Hello World add");
});
});
group("family", () {
test("NotifierProvider build", () {
final container = ProviderContainer();
expect(helloNotifierFProvider, isA<HelloNotifierFFamily>());
expect(container.read(helloNotifierFProvider(init: "Hello World")),
"Hello World");
});
test("NotifierProvider add", () {
final container = ProviderContainer();
expect(helloNotifierFProvider, isA<HelloNotifierFFamily>());
expect(container.read(helloNotifierFProvider(init: "Hello World")),
"Hello World");
container
.read(helloNotifierFProvider(init: "Hello World").notifier)
.add("add");
expect(container.read(helloNotifierFProvider(init: "Hello World")),
"Hello World add");
});
});
}
AsyncNotifierProvider
AsyncNotifierProvider
test/riverpod_generator/async_notifier_provider_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'async_notifier_provider_test.g.dart';
class HelloAsyncNotifier extends _$HelloAsyncNotifier {
Future<String> build() {
return Future.value("Hello AsyncNotifier");
}
void add(String s) async {
state = const AsyncLoading();
state = await AsyncValue.guard(() => Future.value("${state.value} $s"));
}
}
class HelloAsyncNotifierF extends _$HelloAsyncNotifierF {
Future<String> build({required String init}) {
return Future.value(init);
}
void add(String s) async {
state = const AsyncLoading();
state = await AsyncValue.guard(() => Future.value("${state.value} $s"));
}
}
void main() {
group("basic", () {
test("AsyncNotifierProvider build", () async {
final container = ProviderContainer();
expect(
helloAsyncNotifierProvider, isA<AutoDisposeAsyncNotifierProvider>());
expect(container.read(helloAsyncNotifierProvider), isA<AsyncLoading>());
// AsyncLoding から AsyncDataになるのを待つ
await Future<void>.value();
expect(
container.read(helloAsyncNotifierProvider), isA<AsyncData<String>>());
expect(container.read(helloAsyncNotifierProvider).value,
"Hello AsyncNotifier");
});
test("AsyncNotifierProvider add", () async {
final container = ProviderContainer();
expect(
helloAsyncNotifierProvider, isA<AutoDisposeAsyncNotifierProvider>());
expect(container.read(helloAsyncNotifierProvider), isA<AsyncLoading>());
await Future<void>.value();
expect(
container.read(helloAsyncNotifierProvider), isA<AsyncData<String>>());
expect(container.read(helloAsyncNotifierProvider).value,
"Hello AsyncNotifier");
container.read(helloAsyncNotifierProvider.notifier).add("add");
expect(container.read(helloAsyncNotifierProvider), isA<AsyncLoading>());
// AsyncLoding から AsyncDataになるのを待つ
await Future<void>.value();
expect(
container.read(helloAsyncNotifierProvider), isA<AsyncData<String>>());
expect(container.read(helloAsyncNotifierProvider).value,
"Hello AsyncNotifier add");
});
});
group("family", () {
test("AsyncNotifierProvider build", () async {
final container = ProviderContainer();
expect(helloAsyncNotifierFProvider, isA<HelloAsyncNotifierFFamily>());
expect(
container
.read(helloAsyncNotifierFProvider(init: "Hello AsyncNotifier")),
isA<AsyncLoading>());
// AsyncLoding から AsyncDataになるのを待つ
await Future<void>.value();
expect(
container
.read(helloAsyncNotifierFProvider(init: "Hello AsyncNotifier")),
isA<AsyncData<String>>());
expect(
container
.read(helloAsyncNotifierFProvider(init: "Hello AsyncNotifier"))
.value,
"Hello AsyncNotifier");
});
test("AsyncNotifierProvider add", () async {
final container = ProviderContainer();
expect(helloAsyncNotifierFProvider, isA<HelloAsyncNotifierFFamily>());
expect(
container
.read(helloAsyncNotifierFProvider(init: "Hello AsyncNotifier")),
isA<AsyncLoading>());
await Future<void>.value();
expect(
container
.read(helloAsyncNotifierFProvider(init: "Hello AsyncNotifier")),
isA<AsyncData<String>>());
expect(
container
.read(helloAsyncNotifierFProvider(init: "Hello AsyncNotifier"))
.value,
"Hello AsyncNotifier");
container
.read(
helloAsyncNotifierFProvider(init: "Hello AsyncNotifier").notifier)
.add("add");
expect(
container
.read(helloAsyncNotifierFProvider(init: "Hello AsyncNotifier")),
isA<AsyncLoading>());
// AsyncLoding から AsyncDataになるのを待つ
await Future<void>.value();
expect(
container
.read(helloAsyncNotifierFProvider(init: "Hello AsyncNotifier")),
isA<AsyncData<String>>());
expect(
container
.read(helloAsyncNotifierFProvider(init: "Hello AsyncNotifier"))
.value,
"Hello AsyncNotifier add");
});
});
}
FutureProvider
FutureProvider
test/riverpod_generator/future_provider_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'future_provider_test.g.dart';
Future<String> helloFuture(HelloFutureRef ref) {
return Future.value("Hello Future");
}
Future<String> helloFutureF(HelloFutureFRef ref, {required String init}) {
return Future.value("Hello Future");
}
void main() {
group("basic", () {
test("FutureProvider", () async {
final container = ProviderContainer();
expect(helloFutureProvider, isA<AutoDisposeFutureProvider>());
expect(container.read(helloFutureProvider), isA<AsyncLoading>());
// AsyncLoding から AsyncDataになるのを待つ
await Future<void>.value();
expect(
container.read(helloFutureProvider),
isA<AsyncData<String>>().having((s) => s.value, "", "Hello Future"),
);
expect(container.read(helloFutureProvider).value, "Hello Future");
});
});
group("family", () {
test("FutureProvider", () async {
final container = ProviderContainer();
expect(helloFutureFProvider, isA<HelloFutureFFamily>());
expect(container.read(helloFutureFProvider(init: "Hello Future")),
isA<AsyncLoading>());
// AsyncLoding から AsyncDataになるのを待つ
await Future<void>.value();
expect(
container.read(helloFutureFProvider(init: "Hello Future")),
isA<AsyncData<String>>().having((s) => s.value, "", "Hello Future"),
);
expect(container.read(helloFutureFProvider(init: "Hello Future")).value,
"Hello Future");
});
});
}
その他
非 AutoDispose 化
keepAlive
にtrue
を指定すると、非 AutoDispose になるようです。
- @riverpod
+ @Riverpod(keepAlive: true)
build.yaml
test/riverpod_generator/配下でコード生成するために設定しました。
build.yaml
targets:
$default:
sources:
include:
- $package$
- pubspec.yaml
- lib/**
- test/riverpod_generator/**
思ったことメモ
-
StateProvider は、これまで StateNotifierProvider で代替可能だったように、今後は、(Async)NotifierProvider でも代替可能だと思われます。一方で、StateProvider は、class 定義せずに気軽に使える点にメリットを感じているため、代替せずに利用継続していくのも良いのではと思いました。
-
プロバイダが自動生成されるため、例えば、「NotifierProvieder の class 定義」と、その class 定義から「自動生成されるプロバイダのインスタンス」が、1:1 になるように思われる。
1:多、になるようにプロバイダのインスタンスを複数生成したい場合(この場合があるのか?)、どうやるか?
-
StateProvider は十分シンプルなため、ジェネレータで自動生成する必要が無いため、サポートしない?。 ↩︎
Discussion