首页 > 解决方案 > 在riverpod中,如何编写一个异步设置(仅一次)的StateNotifier

问题描述

这里是riverpod的新手。(使用 Flutter 和 hooks_riverpod,顺便说一句)。

使用 Hive 存储项目的相关列表。我需要调用Hive.initFlutter并等待 Hive 被初始化,并在我的应用程序加载时执行同样的操作来打开配置单元框。之后,对 Hive 的调用是同步的。

我最初的想法(尽管我愿意接受更好的想法)是创建一个包含两个列表的 StateNotifier。此通知程序可能有一个异步的 setUp 函数。这是简化后的样子:

class ItemsNotifier extends StateNotifier<ItemsState> {
  ItemsNotifier() : super(ItemsState([], []));

  setUp() async {
    await Hive.initFlutter();
    // What is ItemDao? It's a data accessor object singleton used to house Hive logic.
    await ItemDao().openBoxes();
    // Putting a breakpoint here, I can see by calling `ItemDao().list1` etc that the lists have loaded with items as expected, but setting state here does not trigger a rebuild of the consumer widget.
    state.list1 = ItemDao().list1;
    state.list2 = ItemDao().list2;
  }

  ...getters and setters and other functions omitted...
}

final itemsProvider = StateNotifierProvider<ItemsNotifier, ItemsState>((ref) {
  final notifier = ItemsNotifier();
  notifier.setUp(); // I've never seen anything to suggest that calling an async setUp method here is supported, it's just something I tried.
  return notifier;
});

class ItemsState {
  List<Item> list1;
  List<Item> list2;
  ItemsState(this.list1, this.list2);
}

正如评论中提到的,我在构造 itemsProvider 时调用了一个异步 setUp 方法。我在设置方法和我的消费者小部件中放置了一个断点。首先,小部件内的断点被捕获,我们看到它list1是空的,正如预期的那样。接下来是 setup 方法中的断点。我们看到 ItemDao().list1 充满了项目,因此从 Hive 加载成功。所以我希望调用state.list1 =会导致消费者像往常一样重新加载。但事实并非如此。小部件中的断点不再捕获,小部件保持为空。可能是因为 Riverpod 不希望异步方法从 StateNotifierProvider 构造函数内部更改状态。

所以这个问题的一个简单解决方案可能只是回答我应该在应用程序的哪个位置调用 setUp()?它需要在应用程序启动时只运行一次的地方。在某个有状态小部件的 initState 中?这感觉不太对......正如我所说,我是使用riverpod的新手。

或者,如果您有另一种(更好的)方法来构建它,那也会有所帮助。

考虑的解决方案:

我会注意到我也尝试使用 Riverpod 的FutureProvider。它适用于加载列表。但是,正如文档中所述,FutureProvider 不能像 StateNotifier 那样扩展,所以我不确定将自定义设置器和获取器放在哪里。如果我为每个列表写了一个 FutureProvider,那将无法处理 Hive.initFlutter 应该只被调用一次的事实。我可以找到解决此问题的方法,但它有点笨拙,并且认为如果有更多经验的人建议我会更好。StreamProvider似乎与 FutureProvider 基本相同。也许有一种方法可以在 StateNotifierProvider 中组成 FutureProvider?真的不确定那会是什么样子。

标签: flutterriverpodflutter-hive

解决方案


推荐阅读