flutter Riverpod StateNotifier在父提供程序刷新时丢失状态

c7rzv4ha  于 2023-01-02  发布在  Flutter
关注(0)|答案(1)|浏览(184)

我一直在尝试找出一个解决方案,但没有运气。这里的关键问题是,当你有一个StateNotifier依赖于另一个提供者,一个来自父提供者的新鲜将导致StateNotifier被重新生成,并导致现有的状态丢失。我将使用一个简单的例子来解释我的问题。以下是提供者:

class Pair {
  final int parentValue;
  final int childValue;

  Pair({required this.parentValue, required this.childValue});

  Pair copyWith({int? parentValue, int? childValue}) {
    return Pair(
        parentValue: parentValue ?? this.parentValue,
        childValue: childValue ?? this.childValue
    );
  }
}

class PairNotifier extends StateNotifier<Pair> {
  // parentValue comes from counterProvider but childValue is maintained in existing notifier
  PairNotifier(int parentValue): super(Pair(parentValue: parentValue, childValue: 0));

  Pair increment() {
    final value = state.childValue + 1;
    state = state.copyWith(childValue: value);
    return state;
  }
}

final counterProvider = StateProvider((ref) => 0);

final pairStateProvider = StateNotifierProvider<PairNotifier, Pair>((ref) {
  //Image there are more watch in real world case.
  final parentValue = ref.watch(counterProvider); 
  // when counter is updated, PairNotifier is regenerated therefore childValue is lost.
  return PairNotifier(parentValue);
});

我想知道是否有一种方法可以在所有的父提供程序刷新时保留现有的状态。当然应该有一个优雅的解决方案,因为这个库已经存在了相当长的一段时间。

jdzmm42g

jdzmm42g1#

我也遇到了这些问题,实际上有两种类型的引用对象WidgetRefProviderRef

  • 在小部件树内使用的简单WidgetRef
  • ProviderRef用于在提供程序之间进行通信

因此,在widget中,您将看到提供者及其值,但在我们尝试查看另一个提供者中的提供者的情况下,实际上我们需要读取另一个提供者中的提供者数据。如果我们查看提供者数据,当另一个提供者数据被更改/操作时,它也会更改。
简言之,使用ref.read() method

final counterProvider = StateNotifierProvider<Counter, int>((ref) {
  return Counter(ref);
});

class Counter extends StateNotifier<int> {
  Counter(this.ref): super(0);

  final Ref ref; //it is provided ref

  void increment() {
    // Counter can use the "ref" to read other providers

    final repository = ref.read(repositoryProvider);

    //in side provider we dont want to watch any changes 
    //we only need to read the data of other provider
    repository.post('...');
  }
}

要了解更多信息,请访问official doc

相关问题