1
2

StateNotifierProviderはasyncを使えない…

StateNotifierの初期値にDBや内部ストレージから非同期で取得した値をセットしたい!
というケースは多々あると思います。

class FormItemList extends StateNotifier<List<Item>> {
  FormItemList(List<Item> initialState) : super(initialState);

  void set({required List<Item> itemList}) {
    state = itemList;
  }

  Future<List<Item>> addNewItem({
    required List<Item> itemList,
  }) async {

    state = [...state, ...itemList];
    return state;
  }
}

このようなStateNoriferをproviderで提供するとします。
非同期関数で取得した値を初期値として渡してあげる場合、以下のように書きたくなりますが、StateNotifierProviderの初期化メソッド内ではasync/awaitを使用できません。

final formItemProvider = StateNotifierProvider<FormItemList, List<Item>>((ref) async{
    // NG
    await initialItem = ref.watch(hogeProvider).fetch();
    return FormItemList(initialItem);
});

これと同様のことを実現するには、まずStateNotifierに初期化用のメソッドを用意してあげます。

class FormItemList extends StateNotifier<List<Item>> {
  FormItemList(List<Item> initialState) : super(initialState);

    //初期化メソッドを追加
    Future<void> initialize({required Ref ref}) async {
        // ここで非同期処理を行う
        final List<Item> initialItem = await ref.watch(hogeProvider).fetch();
        state = initialItem
    }

    // 以下略
}

StateNotifierProviderの初期化時にこのメソッドを呼んであげればOKです

final formItemProvider = StateNotifierProvider<FormItemList, List<Item>>((ref) {
   
   //空のリストでインスタンスを作成 
  final notifier = FormItemList([]);

  //初期化メソッドを呼び出す
  notifier.initialize(ref: ref);
  
  return notifier;
});

このように記述することでformItemProviderの初回呼び出し時に、非同期で取得した初期値をセットしたStateNotifierを提供することができます。
当たり前といえば当たり前な方法ですね!

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2