Search code examples
flutterriverpodriverpod-generator

After Riverpod state update on one widget, ref.watch doesn't trigger on my other widget


I'm busy implementing a simple counter using riverpod. From the examples I've seen, the riverpod state is updated on one widget (by doing something like ref.read(counterProvider.notifier).increment()) and changes to state are watched on the same widget. When I try this it works as expected, using ref.watch(counterProvider) in the build method of the same widget. The counter is updated on the UI.

My problem comes in when I update the counter on one widget, and watch for changes to the counter state on another widget (these widgets are two different tabs in a TabView). So basically my increment button is on one tab, and the value of the counter is displayed on the next tab. In this scenario, the counter doesn't get updated.

The weird thing is, if I add a ref.watch on the same widget where I do the state update, the ref.watch on the second tab also starts working and updates the UI correctly on that tab.

Anyone know why this might be happening? Both of these widgets are ConsumerStatefulWidgets and my ProviderScope is at the root of my app. I'm using riverpod V2, with the code generation.

My provider:

part 'counter.provider.g.dart';

@riverpod
class Counter extends _$Counter {
  @override
  int build() {
    return 2;
  }

  void increment() {
    state++;
  }
}

First widget (state update):

ref.read(counterProvider.notifier).increment();

Second widget (state reading):

var x = ref.watch(counterProvider);

Solution

  • Providers annotated with @riverpod will be disposed automatically when it is not being watched or listened. It seems like your counterProvider is getting disposed when switching to another tab.

    You can add a print statement to verify that.

    @override
    int build() {
      ref.onDispose(() {
        print('disposed');
      });
      return 2;
    }