【问题标题】:Riverpod: Recompute a provider providing a list of items on receiving updatesRiverpod:重新计算提供者在接收更新时提供项目列表
【发布时间】:2021-04-19 18:21:10
【问题描述】:

我有一个简单的用例,我正在尝试重新计算提供者,提供有关监视项目提供者的项目列表,如下所示:

final itemProvider = StateProvider<Item>((ref) {
    return Item() ;
});

final itemListProvider = Provider<List<Item>>((ref) {
 watch(itemProvider);
...//do something to compute new list
 return computedList ;
});

我希望 itemListProvider 在 itemProvider 的状态从外部更改时自动重新计算,以便 itemListProvider 继续将新项目添加到它提供的现有列表中。 有没有办法使用 Riverpod 以上述特定方式实现这一目标? 我知道我可以使用 StateNotifierProvider 或 StateProvider 并使用状态分配调用更新 itemList,但我期待以被动方式进行。

感谢任何帮助或指导。谢谢!

【问题讨论】:

    标签: flutter riverpod


    【解决方案1】:

    这可以通过单个 StateNotifierProvider 轻松完成。

    class ItemList extends StateNotifier<List<Item>> {
      ItemList() : super([]);
    
      static final provider = StateNotifierProvider<ItemList, List<Item>>((ref) => ItemList());
    
      Item _current = Item();
      Item get current => _current;
    
      void addItem(Item item) {
        _current = item;
        state = [...state, item];
      }
    }
    

    用法:

    // Add an item, which updates the current item
    watch(ItemList.provider.notifier).addItem(item);
    
    // Get the current item
    final currentItem = watch(ItemList.provider.notifier).current;
    
    // Get the List<Item> from state
    final itemList = watch(ItemList.provider);
    

    如果您真的想要避免使用 StateNotifierProvider,您可以执行以下操作,但我强烈建议您使用第一种方法。总之:

    final itemProvider = StateProvider<Item>((ref) => Item());
    
    final itemListProvider = StateProvider<List<Item>>((ref) => []);
    
    final computedListProvider = Provider<List<Item>>((ref) {
      final item = ref.watch(itemProvider);
      final itemList = ref.watch(itemListProvider);
      WidgetsBinding.instance?.addPostFrameCallback((_) {
        if (itemList.state.contains(item.state)) return;
        itemList.state = [...itemList.state, item.state];
      });
    
      return itemList.state;
    });
    

    【讨论】:

    • 感谢您的回复!但是,我正在寻找更好的替代方案,或者可能是提供者可以使用现有数据和新数据计算自身而无需外部 addToList 状态调用的功能。可以以某种方式完成吗?
    • 我不确定您为什么要以这种方式使事情复杂化。您能否详细说明为什么 StateNotifier 不适用于您的用例?
    • 不幸的是:(
    • @AkashGorai 好的,我添加了一个替代解决方案来完成您在问题中开始的内容。
    • 我没有意识到我们可以在这里使用 postFrameCallback :D.
    【解决方案2】:

    最好的方法是

    1. 对于应作为提供程序的一部分进行评估的任何输入参数,您可以使用riverPod .family。链接在这里 (https://riverpod.dev/docs/concepts/modifiers/family/)

    2. 或者,如果 itemProvider 更新,则应重新评估文档 itemListProvider。如果它不适合您的用例,那么在您的小部件中,您可以调用 ref.refresh 重新评估提供程序。对于 Refresh 执行如下操作并将您的提供者更改为 FutureProvider

      未来 _refresh(){ ref.refresh(itemListProvider); 返回 ref.read(itemListProvider.future); }

    【讨论】:

      猜你喜欢
      • 2022-11-11
      • 2022-01-07
      • 2021-05-17
      • 2021-10-13
      • 2021-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      相关资源
      最近更新 更多