Flutter: Riverpod の StateNotifier の更新タイミングの仕様

Flutter: Riverpod の StateNotifier の更新タイミングの仕様

August 20, 2022

掲題について、勝手に勘違いしていたので、反省も込めてここにメモ。

要約 #

StateNotifier のステートが更新されたときは………

@override
Widget build(context, ref) {
  // リビルドされて表示が更新される
  final myCounterState = ref.watch(myCounterStateProvider);
  return Text('$myCounterState');
}
@override
Widget build(context, ref) {
  // リビルドされないため表示は更新されない
  final myCounterStateNotifier = ref.watch(myCounterStateProvider.notifier);
  return Text('${myCounterState.current}');
}

検証結果 #

Screen

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

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

/*
  State
*/

final myCounterStateProvider = StateNotifierProvider<MyCounterState, int>((
  ref,
) {
  return MyCounterState();
});

class MyCounterState extends StateNotifier<int> {
  MyCounterState() : super(0);

  int get current => state;

  void increment() => state++;
}

/*
  Widget
*/

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(context) {
    return MaterialApp(
      home: Scaffold(
        body: SizedBox(
          width: double.infinity,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: const [
              MyStateWidget(),
              MyStateNotifierWidget(),
              MyButtonWidget(),
            ],
          ),
        ),
      ),
    );
  }
}

class MyStateWidget extends ConsumerWidget {
  const MyStateWidget({super.key});

  @override
  Widget build(context, ref) {
    final myCounterState = ref.watch(myCounterStateProvider);

    return Text('myCounterState: $myCounterState');
  }
}

class MyStateNotifierWidget extends ConsumerWidget {
  const MyStateNotifierWidget({super.key});

  @override
  Widget build(context, ref) {
    final myCounterStateNotifier = ref.watch(myCounterStateProvider.notifier);

    return Text(
      'myCounterStateNotifier.current: ${myCounterStateNotifier.current}',
    );
  }
}

class MyButtonWidget extends ConsumerWidget {
  const MyButtonWidget({super.key});

  @override
  Widget build(context, ref) {
    final myCounterStateNotifier = ref.watch(myCounterStateProvider.notifier);

    return ElevatedButton(
      onPressed: myCounterStateNotifier.increment,
      child: const Icon(Icons.add),
    );
  }
}