🧩 一、什么是 Riverpod
Riverpod 是 Flutter 的一种状态管理框架,由 Provider 的作者重新设计,
目标是:更安全、更灵活、更强大。
相比传统 provider:
- ✅ 不依赖 BuildContext(可以在任意位置使用)
- ✅ 自动管理生命周期(不容易内存泄漏)
- ✅ 支持热重载(调试方便)
- ✅ 支持异步(如网络请求)
- ✅ 支持依赖组合(Provider 可以依赖其他 Provider)
🚀 二、安装
在 pubspec.yaml 中添加依赖:
dependencies:
flutter_riverpod: ^2.5.1
然后在根组件包裹 ProviderScope:
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
const ProviderScope(
child: MyApp(),
),
);
}
📦 三、常见 Provider 类型
1️⃣ Provider(只读、纯数据)
适用于常量或计算值。
final nameProvider = Provider((ref) => 'Lin Jianyou');
class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final name = ref.watch(nameProvider);
return Text('Hello, $name');
}
}
2️⃣ StateProvider(可变状态)
适用于简单的局部状态(例如计数器)。
final counterProvider = StateProvider<int>((ref) => 0);
class CounterWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Column(
children: [
Text('Count: $count'),
ElevatedButton(
onPressed: () => ref.read(counterProvider.notifier).state++,
child: const Text('Increment'),
),
],
);
}
}
3️⃣ StateNotifierProvider(复杂状态)
适用于有业务逻辑的状态,比如 Todo、登录状态等。
// 状态类
class Counter extends StateNotifier<int> {
Counter() : super(0);
void increment() => state++;
void reset() => state = 0;
}
// Provider
final counterNotifierProvider = StateNotifierProvider<Counter, int>((ref) {
return Counter();
});
// 使用
class CounterWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterNotifierProvider);
final counter = ref.read(counterNotifierProvider.notifier);
return Column(
children: [
Text('Count: $count'),
ElevatedButton(
onPressed: counter.increment,
child: const Text('Add'),
),
],
);
}
}
4️⃣ FutureProvider(异步请求)
适用于 异步数据获取(网络请求、数据库等)。
final userProvider = FutureProvider<String>((ref) async {
await Future.delayed(const Duration(seconds: 1));
return 'User: Lin';
});
class UserWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final userAsync = ref.watch(userProvider);
return userAsync.when(
data: (data) => Text(data),
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
);
}
}
5️⃣ StreamProvider(流式数据)
适用于如 WebSocket、数据库订阅等持续变化的数据。
final timeProvider = StreamProvider<int>((ref) async* {
for (var i = 0; i < 10; i++) {
await Future.delayed(const Duration(seconds: 1));
yield i;
}
});
class TimeWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final time = ref.watch(timeProvider);
return time.when(
data: (value) => Text('Time: $value'),
loading: () => const CircularProgressIndicator(),
error: (e, _) => Text('Error: $e'),
);
}
}
🧠 四、Provider 的依赖与组合
你可以让一个 provider 依赖另一个 provider:
final priceProvider = Provider((ref) => 100);
final taxProvider = Provider((ref) => 0.1);
final totalPriceProvider = Provider((ref) {
final price = ref.watch(priceProvider);
final tax = ref.watch(taxProvider);
return price * (1 + tax);
});
🧭 五、监听 Provider 变化(ref.listen)
ref.listen 用于在值变化时执行副作用(比如跳转、弹窗等)。
ref.listen<int>(counterProvider, (previous, next) {
if (next > 10) {
print('超过10了!');
}
});
🧩 六、Riverpod 架构推荐
文件结构建议:
lib/
├─ main.dart
├─ providers/
│ ├─ user_provider.dart
│ ├─ counter_provider.dart
├─ models/
│ ├─ user.dart
├─ screens/
│ ├─ home_screen.dart
│ ├─ profile_screen.dart
🔧 七、调试与工具
可视化调试: 安装 Riverpod Devtools
dart pub global activate riverpod_cli
riverpod watch
在 Flutter DevTools 中能看到 provider 状态变化。
🧩 八、推荐组合
| 场景 | 推荐 Provider 类型 |
|---|---|
| 简单计数 | StateProvider |
| 网络请求 | FutureProvider |
| 长连接流 | StreamProvider |
| 复杂业务逻辑 | StateNotifierProvider |
| 常量/配置 | Provider |
🪄 九、官方示例架构推荐(Clean + State Management)
官方示例架构推荐(Clean + State Management)
Flutter 团队在官方 sample 中(如 Flutter Architecture Samples)推荐:
lib/
├─ data/ ← Repository 层
├─ models/ ← 业务数据模型
├─ providers/ ← 状态定义(用 Provider / Riverpod)
├─ screens/ ← UI 层
└─ main.dart
并使用:
-
UI 负责显示 (ConsumerWidget)
-
Provider/Riverpod 负责状态与逻辑
-
Repository 负责网络或数据库