看来新的项目有用到之前没用过的库,所以需要了解一下。
各个状态库描述
riverpod,riverpod-annotation,flutter hook,hooks-riverpod 这些有没有类似递进的关系,这样的话,我好一步一步了解,你也可以补充我漏掉的环节
让我帮你梳理这些库的递进关系和学习路径:
riverpod
(基础库)- 这是最基础的库,提供了核心的状态管理功能
- 主要概念:Provider, StateNotifier, ProviderContainer
// 基础写法
final counterProvider = StateNotifierProvider<Counter, int>((ref) {
return Counter();
});
class Counter extends StateNotifier<int> {
Counter() : super(0);
void increment() => state++;
}flutter_riverpod
(Flutter 集成)- 在
riverpod
基础上增加了 Flutter 集成 - 提供了 ConsumerWidget, ConsumerStatefulWidget 等
class MyWidget extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Text('$count');
}
}- 在
riverpod_annotation
(简化语法)- 通过代码生成简化 Provider 的创建
- 引入了 @riverpod 注解
class Counter extends _$Counter {
int build() => 0;
void increment() => state++;
}flutter_hooks
(状态逻辑复用)- 提供了一种新的状态管理方式
- 主要用于复用状态逻辑
class Example extends HookWidget {
Widget build(BuildContext context) {
final controller = useTextEditingController();
return TextField(controller: controller);
}
}hooks_riverpod
(完整集成)- 结合了
flutter_riverpod
和flutter_hooks
- 提供了 HookConsumerWidget 等组件
class Example extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final controller = useTextEditingController();
final count = ref.watch(counterProvider);
return TextField(controller: controller);
}
}- 结合了
学习建议:
- 先学习
riverpod
的核心概念 - 了解
flutter_riverpod
如何与 Flutter 集成 - 学习使用
riverpod_annotation
简化代码 - 如果需要处理复杂状态逻辑,学习
flutter_hooks
- 最后掌握
hooks_riverpod
的完整功能
补充一些重要的中间环节:
Provider 的不同类型:
- Provider
- StateProvider
- StateNotifierProvider
- FutureProvider
- StreamProvider
状态管理的模式:
- 依赖注入
- 状态监听
- 状态修改
生命周期管理:
- autoDispose
- family
- 缓存策略
这样的学习路径会让你逐步深入理解整个生态系统。每一步都建立在前一步的基础上,让学习过程更加自然。
状态库实现对比
你给出一个最小验证例子,包含每一个库的单独的使用,基本实现相同的功能的页面,这样我就能更好的理解了
我来帮你创建一个简单的计数器页面,用不同的库来实现,这样你就能看到它们的区别。
使用纯
riverpod
:// main.dart
import 'package:flutter/material.dart';
import 'package:riverpod/riverpod.dart';
// 定义 provider
final counterProvider = StateNotifierProvider<Counter, int>((ref) => Counter());
class Counter extends StateNotifier<int> {
Counter() : super(0);
void increment() => state++;
}
void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
class CounterPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Riverpod Counter')),
body: Center(
child: Consumer(
builder: (context, ref, child) {
final count = ref.watch(counterProvider);
return Text('Count: $count');
},
),
),
floatingActionButton: Consumer(
builder: (context, ref, child) {
return FloatingActionButton(
onPressed: () => ref.read(counterProvider.notifier).increment(),
child: Icon(Icons.add),
);
},
),
);
}
}使用
flutter_riverpod
:// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final counterProvider = StateNotifierProvider<Counter, int>((ref) => Counter());
class Counter extends StateNotifier<int> {
Counter() : super(0);
void increment() => state++;
}
void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
class CounterPage extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Scaffold(
appBar: AppBar(title: Text('Flutter Riverpod Counter')),
body: Center(
child: Text('Count: $count'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => ref.read(counterProvider.notifier).increment(),
child: Icon(Icons.add),
),
);
}
}使用
riverpod_annotation
:// counter_provider.dart
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'counter_provider.g.dart';
class Counter extends _$Counter {
int build() => 0;
void increment() => state++;
}
// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'counter_provider.dart';
void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
class CounterPage extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Scaffold(
appBar: AppBar(title: Text('Riverpod Annotation Counter')),
body: Center(
child: Text('Count: $count'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => ref.read(counterProvider.notifier).increment(),
child: Icon(Icons.add),
),
);
}
}使用
flutter_hooks
:// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(MyApp());
}
class CounterPage extends HookWidget {
Widget build(BuildContext context) {
final counter = useState(0);
return Scaffold(
appBar: AppBar(title: Text('Flutter Hooks Counter')),
body: Center(
child: Text('Count: ${counter.value}'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => counter.value++,
child: Icon(Icons.add),
),
);
}
}使用
hooks_riverpod
:// counter_provider.dart
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'counter_provider.g.dart';
class Counter extends _$Counter {
int build() => 0;
void increment() => state++;
}
// main.dart
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'counter_provider.dart';
void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
class CounterPage extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
// 使用 hooks 来管理本地状态
final isEnabled = useState(true);
// 使用 riverpod 来管理全局状态
final count = ref.watch(counterProvider);
return Scaffold(
appBar: AppBar(title: Text('Hooks Riverpod Counter')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Count: $count'),
Switch(
value: isEnabled.value,
onChanged: (value) => isEnabled.value = value,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: isEnabled.value
? () => ref.read(counterProvider.notifier).increment()
: null,
child: Icon(Icons.add),
),
);
}
}使用
provider
// 1. Provider Version
// main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// 定义数据模型
class CounterModel with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => CounterModel(),
child: MyApp(),
),
);
}
class CounterPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Provider Counter')),
body: Center(
child: Consumer<CounterModel>(
builder: (context, counter, child) {
return Text('Count: ${counter.count}');
},
),
),
floatingActionButton: Consumer<CounterModel>(
builder: (context, counter, child) {
return FloatingActionButton(
onPressed: () => counter.increment(),
child: Icon(Icons.add),
);
},
),
);
}
}使用
pure flutter
// 2. Pure Flutter Version (StatefulWidget)
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class CounterPage extends StatefulWidget {
_CounterPageState createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int _count = 0;
void _increment() {
setState(() {
_count++;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Pure Flutter Counter')),
body: Center(
child: Text('Count: $_count'),
),
floatingActionButton: FloatingActionButton(
onPressed: _increment,
child: Icon(Icons.add),
),
);
}
}
主要区别:
riverpod
: 需要使用 Consumer 包装需要访问状态的 Widgetflutter_riverpod
: 提供了 ConsumerWidget 简化代码riverpod_annotation
: 使用代码生成简化 provider 的创建flutter_hooks
: 用于管理本地状态,提供了很多内置的 hookshooks_riverpod
: 结合了 hooks 和 riverpod 的优点
要运行这些例子,需要在 pubspec.yaml 中添加对应的依赖:
dependencies: |
每个实现都完成了相同的基本功能,但使用了不同的方式。从中你可以看到代码的演进和简化过程。