Widgetの再構築が不要なときに使う context.read
以下のようにProviderを watch
する方法があります。
Widget build(BuildContext context, ScopedReader watch) {
// StateProvider<int>
final counter = watch(counterProvider);
return ElevatedButton(
onTap: () => counter.state++,
child: Text('+1'),
);
}
しかし、例えば以下の状況では、Counterの値を表示していないため watch
する必要がありません。
Counterの値が変更された時、無駄にElevatedButton Widgetが再構築されてしまいます。
ここで行いたいのは、ボタンを押したときにCounterの値を変更したいだけです。
そこで context.read
を使用して、以下のように書き換えることができます。
Widget build(BuildContext context, ScopedReader watch) {
return ElevatedButton(
onTap: () => context.read(counterProvider).state++,
child: Text('+1'),
);
}
watch
が無くなったので、 Counterの値が変更されてもElevatedButtonが再構築されることがなくなりました👏
StateNotifierでは .notifier でOK
Providerによっては、 context.read
を使用せずとも状態を watch
せずに取得する方法が用意されています。
StateNotifierでは .notifier
を使用します。
final counterProvider = StateNotifierProvider<Counter, int>((ref) => Counter());
Widget build(BuildContext context, ScopedReader watch) {
// そのまま `watch` するとStateを取得しますが、 `notifier` を付けることで
// `context.read` を使用した時と同じように、再構築されない `Counter (StateNotifier)` が取得できる
final counter = watch(counterProvider.notifier);
return RaisedButton(
// onPressedなどで使うことができる
onPressed: counter.increase,
child: Text('+1'),
);
}
buildメソッド内では使用しないようにする
参考リンク
context.read(myProvider) | Riverpod