flutter - 在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?真的不确定那会是什么样子。
解决方案
推荐阅读
- angular - Angular httpclient.post 没有创建正确的正文
- html - 为什么我的 :active 选择器在缩放转换时会失去其点击事件状态?
- reactjs - 使用 Link 模块的 Next.js 页面未通过 CSS 导入加载文件
- encoding - HEVC 中 last_sig_coeff_x,y_prefix 标志有多少个上下文?
- jquery - 将同一张表中另一个TD中的TD内容移动
- amazon-web-services - 如何在 RDS MySQL 数据库之前保留 Amazon ElastiCahe Memcached/Redis 并使用 ElastiCache 缓存内容?
- python - 如何在 Atom 中安装 Swampy?
- android - 在 AsyncTask 的 onPostExecute 之后,无法按意图更新 RecyclerView
- opencl - OpenCL 图像对象和边界检查
- vba - 我可以使用 .getpoint 选择圆锥顶部的位置吗