Riverpod2.6.0から変わったこと
Refの書き方が変わった?
remiさんがこんな投稿をXでしておりました。
A new Riverpod version has been released, with a bunch of deprecation notices related to Ref/AutoDispose.
TL;DR: No more "MyProviderRef". Just use "Ref" instead.
による英語からの翻訳
Riverpod の新しいバージョンがリリースされましたが、Ref/AutoDispose に関連する多数の非推奨通知が含まれています。
TL;DR: 「MyProviderRef」はもう不要です。代わりに「Ref」を使用してください。
All docs/examples/lints have been updated accordingly.
Quick-fixes work too.
You can easily migrate using custom_lint --fix
それに伴い、すべてのドキュメント/サンプル/リントを更新しました。
クイックフィックスも使えます。
custom_lint --fix` を使えば簡単に移行できます。
BreakingChangeとかいうのか...
pub.dev
みたら破壊的変更か?
あったようだ。
-
Deprecated all Ref subclasses. Instead, use Ref itself.
-
Deprecated Ref's type argument. Use Ref without its generic parameter instead.
-
Deprecated any Ref member that used Ref's generic (such as Ref.state or Ref.listenSelf). Instead, use a Notifier.
-
Added Notifier.listenSelf, as a replacement to Ref.listenSelf.
-
Ref.watch and other methods now accept auto-dispose providers too.
-
すべてのRefサブクラスを廃止。代わりにRef自身を使用する。
-
Refの型引数を廃止。代わりにジェネリック引数のないRefを使用してください。
-
Refのジェネリックを使用していたRefメンバー(Ref.stateやRef.listenSelfなど)を非推奨としました。代わりにNotifierを使用してください。
-
Ref.listenSelfの代わりにNotifier.listenSelfを追加しました。
-
Ref.watchやその他のメソッドも自動破棄プロバイダーを受け入れるようになりました。
Provider Exampel
こんな感じで使ってみました。確かにRefだけいいのかな...
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'greet.g.dart';
String hello(Ref ref) => "Hello☀️";
(keepAlive: true)
Greet greet(Ref ref) => Greet(ref);
class Greet {
Ref ref;
Greet(this.ref);
void logger() {
final hello = ref.read(helloProvider);
debugPrint(hello);
}
}
FutureProvider Exampel
FutureProviderを使用してAPI通信をするコードを書いた例です。なんかシンプルになったような?
以前はTodoRef
なんて書いてましたね😆
モデルを定義する
import 'package:freezed_annotation/freezed_annotation.dart';
part 'todo.freezed.dart';
part 'todo.g.dart';
class Todo with _$Todo {
const factory Todo({
(0) int userId,
(0) int id,
('') String title,
(false) bool completed,
}) = _Todo;
factory Todo.fromJson(Map<String, Object?> json) => _$TodoFromJson(json);
}
Providerを定義する
今度からRefだけでいいのか?
気になったのは、flutter_riverpod.dart
のモジュールをインポートすることですね。
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_theme_app/todo.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'future.g.dart';
Future<List<Todo>> todos(Ref ref) async {
final dio = Dio();
final response = await dio.get('https://jsonplaceholder.typicode.com/todos/');
return (response.data as List).map((e) => Todo.fromJson(e)).toList();
}
StreamProvider Example
よく使うことがあるCloud Firestoreを例に書いてみた。
モデルを作る。
import 'package:freezed_annotation/freezed_annotation.dart';
part 'chat.freezed.dart';
part 'chat.g.dart';
class Chat with _$Chat {
const factory Chat({
('') String name,
}) = _Chat;
factory Chat.fromJson(Map<String, dynamic> json) => _$ChatFromJson(json);
}
こちらもRefで良いみたいだな。うっかりRiverpodをインポートしてないとRef書いただけでは怒られるのに気づく🔥
他のファイルにまとまっている機能であるモジュールを呼び出してあげよう。
example
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_theme_app/chat.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'chat.g.dart';
(keepAlive: true)
FirebaseFirestore firebaseFirestore(Ref ref) => FirebaseFirestore.instance;
Stream<List<Chat>> chat(Ref ref) {
final store = ref.read(firebaseFirestoreProvider);
final collection = store.collection('cart').snapshots();
return collection
.map((event) => event.docs.map((e) => Chat.fromJson(e.data())).toList());
}
Firebase Authはこんな感じ
Firebase Authenticationでも使うことが多かったので書き直したコードを書いてみた。少しだけだがシンプルになった気がする?
arrow functionみたいな書き方にしてみた。
example
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'auth.g.dart';
(keepAlive: true)
FirebaseAuth firebaseAuth(Ref ref) => FirebaseAuth.instance;
(keepAlive: true)
Stream<User?> authState(Ref ref) =>
ref.watch(firebaseAuthProvider).authStateChanges();
(keepAlive: true)
String? uid(Ref ref) => ref.read(firebaseAuthProvider).currentUser?.uid;
最後に
多くは解説できなかったな。
ざっくりとですが、Riverpod2.6.0からRefだけでよくなったらしい書き方を試してみた。Riverpodは進化するのが早いから常に情報を収集していないといけない。これはWebのフレームワークのNext.js、Nuxt.js、ライブラリであるReact, Vue.jsでも同じですね。
何か変更は出る。常に勉強は必要。
Riverpodが使えれば偉いというわけではないのだ。Dartのコードを書くときにNullable(nullを許容する)やfor文を使った繰り返しだったりロジックを書く為に、データ型や処理の書き方を理解していることが求められる。
こんな感じでね👇
// String?がNullableだよ
(keepAlive: true)
String? uid(Ref ref) => ref.read(firebaseAuthProvider).currentUser?.uid;
皆様も良きFlutter Lifeを😎
Discussion