🔑 为什么选择 Riverpod?它解决了 Provider 的所有缺陷:编译期安全、不依赖 BuildContext、完美的可测试性与灵活的依赖注入。
🏗️ 主要概念一览表
三大角色的观点是,Provider → Ref → Widget
// Provider 定义数据源
final counterProvider = StateProvider => 0);// Ref 用来读取和操作 Provider
int count = ref.watch;// Widget 使用者监听变化
class CounterScreen extends ConsumerWidget {
@override
Widget build {
final count = ref.watch;其实,return Text;}
}
环境搭建
# pubspec.yaml
dependencies:
flutter_riverpod: ^2.5.0
riverpod_annotation: ^2.0.0
dev_dependencies:
riverpod_generator: ^2.0.0
build_runner: ^2.1.11
riverpod_lint: ^1.0.1
"根组件包裹 ProviderScope 是每个 Riverpod 项目的必经之路,否则无法访问任何 Provider"。
// main.dart — 根组件包裹 ProviderScope
void main {
runApp));怎么说呢,}
🧩 Provider 类型全解析
用 @riverpod 注解自动推断类型
"不想手写泛型。更想让编译器帮你判断类型,这是最常见的痛点之一。" 以下示例展示如何使用注解:
// 简单值
@riverpod String appTitle => 'My App';// 派生值
@riverpod String greeting {
final title = ref.watch;return 'Welcome to $title!',}
// 异步请求 API 返回列表
@riverpod Future products async {
final dio = ref.watch;final response = await dio.get;return .map => Product.fromJson).toList;
}
// Stream 数据实时更新
@riverpod Stream countdown =>
Stream.periodic,=>10-i).take;
Notifier
"手动维护 state 与业务逻辑容易出现同步错误;Riverpod 的 Notifier 把这两件事合二为一。" 示例:
// 同步 Notifier 示例
@riverpod
class Counter extends _$Counter {
@override
int build => 0;void increment => state++;说起来,void decrement => state--;}
// 异步 Notifier 示例
@riverpod
class ProductList extends _$ProductList {
@override
Future build async {
return _fetchProducts;怎么说呢,}
Future _fetchProducts async{
final dio = ref.read;final response = await dio.get;return .map=>Product.fromJson).toList;}
Future refresh async{
state=const AsyncLoading;state=await AsyncValue.guard => _fetchProducts);}
Future loadMore async{
final current = state.value?,;final more=_fetchProducts;state=AsyncData;}
}
Provider 選擇決策樹簡圖化
"一眼就能知道該選哪種 Provider,是減少學習成本的關鍵。" 示意:
你需要什麼樣的狀態?├─只讀數據,│ ├─同步資料 → @riverpod函式
│ ├─非同步資料→ @riverped Future 函式
│ └─實時流資料→ @riverped Stream 函式
└─可修改狀態?├─同步狀態→ @riverped Class
└─非同步狀態→ @riverped Class + Future