这里是 Riverpod 的新手。 (顺便说一句,使用 Flutter 和 hooks_riverpod)。
使用 Hive 存储相关的项目列表。我需要调用 Hive.initFlutter
并等待 Hive 初始化,并在我的应用加载时执行相同操作以打开 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 方法。我在 setup 方法和我的消费者小部件中放置了一个断点。首先捕获小部件内的断点,我们看到 list1
为空,正如预期的那样。接下来,setup 方法中的断点会被捕获。我们看到 ItemDao().list1 充满了项目,所以从 Hive 加载成功。所以我希望调用 state.list1 =
会导致消费者像往常一样重新加载。但事实并非如此。小部件中的断点不会再次捕获,小部件保持为空。可能是因为 Riverpod 不希望异步方法从 StateNotifierProvider 构造函数内部更改状态。
所以这个问题的一个简单解决方案可能只是我应该在应用程序中的哪个位置调用 setUp() 的答案?它需要在应用程序启动时只运行一次的地方。在某个有状态小部件的 initState 中?感觉不太对劲……正如我所说,我是使用 riverpod 的新手。
或者,如果您有其他(更好的)方法来构建它,那也会有帮助。
我注意到我也尝试过使用 riverpod 的 FutureProvider。它适用于加载列表。但是,正如文档中所述,FutureProvider 不能像 StateNotifier 那样扩展,所以我不确定我会把自定义的 setter 和 getter 放在哪里。如果我为每个列表编写一个 FutureProvider,那将无法处理 Hive.initFlutter 应该只调用一次的事实。我可以找到解决此问题的方法,但它有点笨拙,并且认为如果有更多经验的人建议我会更好。 StreamProvider 似乎与 FutureProvider 基本相同。也许有一种方法可以在 StateNotifierProvider 中组合 FutureProvider?真的不知道那会是什么样子。