Menu
CoddyTech

Riverpod:StateProvider

本课属于 Coddy Flutter 学习旅程的“状态管理”单元。第 18 课,共 27 课。

Provider 保存一个不会改变的值。对于一个会改变的简单值,比如数字、bool 或 String,使用 StateProvider:

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

读取方式相同:ref.watch(quantityProvider) 会返回这个数字,值改变时,组件会重新构建。

要改变它,请使用 ref.read 获取它的 notifier,也就是保存该值的对象,然后设置它的 state:

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

和 Provider 中一样,在 build 中使用 ref.watch 来显示值,在回调中使用 ref.read 来改变它。改变副本不会产生任何影响:var n = ref.read(quantityProvider); n++; 会让 n 增加 1,而不是改变 provider。只有设置 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 在线编译器