As per the Riverpod documentation, asynchronously we use ref.read such as inside a function and for synchronous code, we use ref.watch such as inside the build method.
Once I press a button, the function with ref.read will fire up and it will be for only one time. Here, I should use ref.watch as it is now inside build method and with onPressed it will be ref.read
Case 1:
// Bad practice
// Documentation says, "DON'T use ref.read inside the build method".
final counterProvider = StateProvider((ref) => 0);
Widget build(BuildContext context, WidgetRef ref) {
StateController counter = ref.read(counterProvider.notifier);
return ElevatedButton(
onPressed: () => counter.state ,
child: const Text('button'),
);
}
Case 2:
// Good Practice
ElevatedButton(
onPressed: () => ref.read(counterProvider.notifier).state ,
child: const Text('button'),
),
Case 3:
// Good Practice
Widget build(BuildContext context, WidgetRef ref) {
StateController counter = ref.watch(counterProvider.notifier);
return ElevatedButton(
onPressed: () => counter.state ,
child: const Text('button'),
);
}
In all 3 cases, code remains asynchronous since it is called only when the button is pressed then why is case1 bad and case 3 good practice?
CodePudding user response:
the docs says you shouldn't use ref.read
inside your build method because it will not cause a rebuild when the state changes, and in most cases you'll need to update your ui.
You can definitely use it inside the build method, but it will just "read" the data, if your state updates, the ui won't, this why you should always use watch
inside your build method, to always update your ui when the state changes.
check this dartpad example from riverpod-v2 docs, try to use read
instead of watch
, it will work, but it's not actually working right? the ui doesn't update when you press the increment button.
CodePudding user response:
As per Remi Rousselet,
"It's about when read/watch are invoked, not when the state change is triggered."