ConsumerWidget 与 ref.watch
本课属于 Coddy Flutter 学习旅程的“状态管理”单元。第 17 课,共 27 课。
任何 widget 只要能获取 ref,就可以读取 provider。要为它提供 ref,需要改两处:
- 将
extends StatelessWidget改为extends ConsumerWidget。 - 给
build添加第二个参数WidgetRef ref。
class CityName extends ConsumerWidget {
const CityName({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final city = ref.watch(cityProvider);
return Text(city);
}
}ref.watch(cityProvider) 会为你提供 provider 的值,这里是文本 Lisbon。每当这个值发生变化时,widget 都会重新构建。如果没有 ref.watch,cityProvider 就只是 provider 本身,而不是它的值。
每个需要某个值的 widget 都可以在自身所在的位置这样获取它。不需要通过构造函数向下传递任何内容,也不需要通过 context 来查找它。
挑战
简单CityName 和 Temperature 显示的是占位内容。让它们读取文件顶部的提供器:
- 将它们都改为
ConsumerWidget。 CityName显示cityProvider的值。Temperature显示temperatureProvider的值,后面跟着°C,字号保持不变。
亲手试试
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final cityProvider = Provider((ref) => 'Lisbon');
final temperatureProvider = Provider((ref) => 21);
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: const CityName()),
body: const Center(child: Temperature()),
),
);
}
}
class CityName extends StatelessWidget {
const CityName({super.key});
@override
Widget build(BuildContext context) {
return const Text('City');
}
}
class Temperature extends StatelessWidget {
const Temperature({super.key});
@override
Widget build(BuildContext context) {
return const Text('0°C', style: TextStyle(fontSize: 64));
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
状态管理中的所有课
4Riverpod
Riverpod:ProviderScopeConsumerWidget 与 ref.watchRiverpod:StateProviderRiverpod:Notifier会监听其他 Provider 的 Provider选择状态的存放位置自己练习: Flutter 在线编译器