skip to Main Content

There is a state provider

final valueStateProvider = StateProvider<int>((ref) => 50);

a possible solution to show modals is

Widget build(BuildContext context, WidgetRef ref) {
  final value = ref.watch(valueStateProvider);
  ref.listen<int>(valueStateProvider, (prev, curr) {
    if (curr == 65) {
      // show a dialog
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Value is 65')),
      );
    }
});
...

but how is it different from the following one since the ref is watched here ?

Widget build(BuildContext context, WidgetRef ref) {
  final value = ref.watch(valueStateProvider);
  if (value == 65) {
      // show a dialog
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Value is 65')),
      );
  }
  ...

Should not the value be updated automatically since watch is used? Then what is the reason to use watch but not read here?

2

Answers


  1. Widget build(BuildContext context, WidgetRef ref) {
      final value = ref.watch(valueStateProvider);
      if (value == 65) {
          // show a dialog
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Value is 65')),
          );
      }
    

    This code has the following bug: every time the Widget is rebuilt (which can happen at any time, Flutter just does it for fun sometimes) and your value is 65 the snackbar is shown. So at worst case every frame a new snackbar is shown.


    ref.watch(valueStateProvider) will rebuild the Widget every time your valueStateProvider changes.

    ref.listen(valueStateProvider) will run the provided callback every time the valueStateProvider changes.

    So in your case you want to use ref.listen!

    Login or Signup to reply.
  2. Listening (ref.listen) does not trigger a rebuild of the widget, whereas ref.watch will trigger the build method whenever there is a change.

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