skip to Main Content

I’m working with Flutter Riverpod and have encountered different behaviors when using ref.watch versus ref.read in my DumTabNotifier class. Here’s a simplified version of my code:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:get/get.dart';

// Notifier class
class DumTabNotifier extends Notifier<DumTabState> {
  final _edtLmp = TextEditingController();

  @override
  DumTabState build() {
    ref.onDispose(() {
      _edtLmp.clear();
    });

    return DumTabState(
      gestationalAgeString: '',
      edd: '',
      eofTrimester: '',
      bofTrimester: '',
      gaWeeks: 0,
      gaDays: 0,
      edtLmp: _edtLmp,
    );
  }

  void calculateFromLmp() {
    DateTime? lmpDT = extractDateFromStringBasedOnLocale(_edtLmp.text);
    if (lmpDT == null) return;

    final todayGlobal = ref.watch(todayGlobalProvider); // or ref.read(todayGlobalProvider)

    // Calculation logic...
  }
}

final dumTabProvider = NotifierProvider<DumTabNotifier, DumTabState>(() {
  return DumTabNotifier();
});

Issue:

When I use ref.watch(todayGlobalProvider) inside calculateFromLmp(), the DumTabNotifier gets disposed and recreated if the todayGlobalProvider changes. I discovered this because the TextEditingController (_edtLmp) clears itself (unwanted behavior) whenever ref.watch is used, indicating that the notifier is being disposed. However, when I replace ref.watch with ref.read(todayGlobalProvider), the DumTabNotifier is not disposed when todayGlobalProvider changes.

Question:

Why does using ref.watch cause the DumTabNotifier to be disposed and recreated, while ref.read does not?

What are the best practices for deciding when to use ref.watch versus ref.read in this context?

Any insights into the behavior and lifecycle management of Riverpod notifiers would be greatly appreciated!


Edit: now I’ve discovered (on riverpod doc) that provider is not recommended to be used with TextEditingControllers. However I do need to access this TextEditingController from several screens.

2

Answers


  1. Ref.read

    The ref.read method is a way to obtain the state of a provider without listening to it.

    It is commonly used inside functions triggered by user interactions.

    DON’T use ref.read inside the build method

    Ref.watch

    ref.watch is used inside the build method of a widget or inside the body of a provider to have the widget/provider listen to a provider

    The watch method should not be called asynchronously, like inside an onPressed of an ElevatedButton. Nor should it be used inside initState and other State life-cycles.In those cases, consider using ref.read instead.

    Login or Signup to reply.
  2. The problem Is on Watch(): It Is used to register the notifier against the context. If you do so, It would be created (if no One Is already present) or, in your case, It Would be destroyed perhaps the widget was be recreated . In the other case if you call read(), It Will not follow the widget Life cycle, It Will execute the function of the listener without any registration. Moreover you should use flutter hooks tò handle this kind of states, and use riverpod only for Global states.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search