Riverpod:ProviderScope
本课属于 Coddy Flutter 学习旅程的“状态管理”单元。第 16 课,共 27 课。
Riverpod 是另一个用于共享状态的包,由和 Provider 同一个人编写,并吸取了一些经验教训。它最大的变化是:provider 不是树中的小部件,而是文件顶部、所有类之外的一个 final 变量:
import 'package:flutter_riverpod/flutter_riverpod.dart';
final quoteProvider = Provider((ref) => 'Small steps, every day.');函数会为 provider 提供它的值。Riverpod 会在小部件首次请求时调用它,并保存结果。
这些值需要存放在某个地方,这就是 ProviderScope 的作用。它只需在 main 中放置一次,包住整个应用:
void main() {
runApp(const ProviderScope(child: MyApp()));
}小部件通过 ref 读取 provider。ConsumerWidget 是一个 StatelessWidget,它的 build 会收到一个 ref:ref.watch(quoteProvider)。如果它上方没有 ProviderScope,这行代码就无处查找,应用会因找不到 No ProviderScope found 而停止。
挑战
简单应用因找不到 No ProviderScope found 而停止。
- 在
main中用ProviderScope包裹MyApp。 - 将引言改为
Small steps, every day.。
亲手试试
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final appNameProvider = Provider((ref) => 'Daily Quote');
final quoteProvider = Provider((ref) => 'Write your quote here.');
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends ConsumerWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final appName = ref.watch(appNameProvider);
final quote = ref.watch(quoteProvider);
return Scaffold(
appBar: AppBar(title: Text(appName)),
body: Center(
child: Text(quote, style: const TextStyle(fontSize: 24)),
),
);
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
状态管理中的所有课
4Riverpod
Riverpod:ProviderScopeConsumerWidget 与 ref.watchRiverpod:StateProviderRiverpod:Notifier会监听其他 Provider 的 Provider选择状态的存放位置自己练习: Flutter 在线编译器