Menu
CoddyTech

Riverpod: StateProvider

CoddyのFlutterジャーニー「状態管理」セクションの一部。レッスン 18/27。

Providerは、変化しない値を保持します。変化する単純な値、つまり数値、bool、Stringには、StateProviderを使います。

final quantityProvider = StateProvider((ref) => 1);

読み取る方法は同じです。ref.watch(quantityProvider)で数値を取得でき、値が変わるとウィジェットが再びビルドされます。

値を変更するには、値を保持するオブジェクトであるnotifierをref.readで取得し、そのstateを設定します。

onPressed: () {
  ref.read(quantityProvider.notifier).state++;
},

Providerと同様に、値を表示するにはbuild内でref.watchを使い、値を変更するにはコールバック内でref.readを使います。また、コピーを変更しても何も変わりません。var n = ref.read(quantityProvider); n++;はnに1を加えるだけで、プロバイダーの値は変わりません。変わるのはstateを設定したときだけです。

challenge icon

チャレンジ

簡単

パンケーキの注文には数量が表示されていますが、ボタンはまだ何もしません。

  • プラスボタンを押すと、quantityProviderの値が1増えます。
  • マイナスボタンを押すと、値が1減りますが、1未満にはなりません。

自分で試してみよう

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

final quantityProvider = StateProvider((ref) => 1);

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: OrderPage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final quantity = ref.watch(quantityProvider);
    return Scaffold(
      appBar: AppBar(title: const Text('Pancakes')),
      body: Center(
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            IconButton(
              icon: const Icon(Icons.remove),
              onPressed: () {},
            ),
            Text('Quantity: $quantity', style: const TextStyle(fontSize: 24)),
            IconButton(
              icon: const Icon(Icons.add),
              onPressed: () {},
            ),
          ],
        ),
      ),
    );
  }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

状態管理のすべてのレッスン

自分で練習してみよう: Flutterオンラインコンパイラ