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 才会生效。
挑战
简单煎饼订单会显示数量,但按钮目前还不起作用。
- 加号会让
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: () {},
),
],
),
),
);
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
状态管理中的所有课
4Riverpod
Riverpod:ProviderScopeConsumerWidget 与 ref.watchRiverpod:StateProviderRiverpod:Notifier会监听其他 Provider 的 Provider选择状态的存放位置自己练习: Flutter 在线编译器