🔥
AutoDisposeAsyncNotifierProviderFamily で無限に build メソッドが走ってしまった件
事象
riverpod の AutoDisposeAsyncNotifierProviderFamily
の build メソッドが無限に呼び出されてしまう。
final todoListProvider =
AutoDisposeAsyncNotifierProviderFamily<TodoListAsyncNotifier, Category, Map<String, Object>>(TodoListAsyncNotifier.new);
class TodoListAsyncNotifier extends AutoDisposeFamilyAsyncNotifier<Category, Map<String, Object>> {
FutureOr<Category> build(Map<String, Object> arg) async {
// ここの build が無限に呼び出される・・・.
final list = await ref.read(todoListRepositoryProvider).fetch();
return Category(id: arg['id'] as String, name: arg['categoryName'] as String, items: list, updatedAt: arg['date'] as DateTime);
}
}
ちなみに riverpod_generator
で生成した provider もアウトでした。(最初はそれでやってました)
FutureOr でない普通の Category を返すだけなら多分発生しなかったと思う・・・。
原因
引数に DateTime.now()
を渡したこと。
開発者曰く、millisecond 単位のデータを渡してしまうと(おそらく)差分が都度発生し、何回も provider が生成されてしまうっぽいです。
final date = DateTime.now();
// これだと無限に生成されてしまう...
final value = ref.watch(todoListProvider(Tuple3('aabbbb', 'category', date)));
対策
millisecond
以下は 0
にしましょう、とのことでした。
もし、millisecond
以下の値も必要であれば別途対策が必要になりそうです。
var date = DateTime.now();
// 適当に second まで値設定する.
date = DateTime(date.year, date.month, date.day, date.hour, date.minute, date.second);
final value = ref.watch(todoListProvider(Tuple3('aabbbb', 'category', date)));
Discussion