Flutter Riverpod状态管理的新纪元告别 Provider 的繁琐拥抱 Riverpod 的简洁与强大。一、为什么选择 Riverpod作为一名追求代码如散文般优雅的 UI 匠人我对状态管理工具有着近乎偏执的要求。Riverpod 不仅解决了 Provider 的上下文依赖问题还带来了编译时安全、代码生成和更好的测试性。这就像从手动调音的钢琴换成了自动校准的演奏级三角钢琴。二、基础概念1. Provider 类型import package:flutter_riverpod/flutter_riverpod.dart; // 简单值 final nameProvider ProviderString((ref) Leopold); // 状态管理 final counterProvider StateProviderint((ref) 0); // 异步数据 final userProvider FutureProviderUser((ref) async { final response await http.get(Uri.parse(/api/user)); return User.fromJson(jsonDecode(response.body)); }); // 计算属性 final greetingProvider ProviderString((ref) { final name ref.watch(nameProvider); return Hello, $name!; });2. ConsumerWidget 使用class CounterPage extends ConsumerWidget { override Widget build(BuildContext context, WidgetRef ref) { final count ref.watch(counterProvider); return Scaffold( appBar: AppBar(title: Text(Counter)), body: Center( child: Text( $count, style: Theme.of(context).textTheme.headlineLarge, ), ), floatingActionButton: FloatingActionButton( onPressed: () ref.read(counterProvider.notifier).state, child: Icon(Icons.add), ), ); } }三、高级用法1. StateNotifier 复杂状态class Todo { final String id; final String title; final bool isCompleted; Todo({ required this.id, required this.title, this.isCompleted false, }); Todo copyWith({String? title, bool? isCompleted}) { return Todo( id: id, title: title ?? this.title, isCompleted: isCompleted ?? this.isCompleted, ); } } class TodoNotifier extends StateNotifierListTodo { TodoNotifier() : super([]); void addTodo(String title) { state [ ...state, Todo( id: DateTime.now().toString(), title: title, ), ]; } void toggleTodo(String id) { state state.map((todo) { if (todo.id id) { return todo.copyWith(isCompleted: !todo.isCompleted); } return todo; }).toList(); } void removeTodo(String id) { state state.where((todo) todo.id ! id).toList(); } } final todoProvider StateNotifierProviderTodoNotifier, ListTodo((ref) { return TodoNotifier(); });2. 依赖注入final apiClientProvider ProviderApiClient((ref) { return ApiClient(baseUrl: https://api.example.com); }); final userRepositoryProvider ProviderUserRepository((ref) { final apiClient ref.watch(apiClientProvider); return UserRepository(apiClient); }); final userListProvider FutureProviderListUser((ref) async { final repository ref.watch(userRepositoryProvider); return repository.getUsers(); });3. 自动刷新与缓存final autoDisposeProvider FutureProvider.autoDisposeListPost((ref) async { // 当不再被监听时自动释放 final response await http.get(Uri.parse(/api/posts)); return jsonDecode(response.body); }); // 带缓存策略 final cachedProvider FutureProviderListPost((ref) async { // 保持 5 分钟缓存 final link ref.keepAlive(); Timer(Duration(minutes: 5), link.close); final response await http.get(Uri.parse(/api/posts)); return jsonDecode(response.body); });四、实战案例主题切换final themeModeProvider StateProviderThemeMode((ref) ThemeMode.system); class ThemeSwitcher extends ConsumerWidget { override Widget build(BuildContext context, WidgetRef ref) { final themeMode ref.watch(themeModeProvider); return DropdownButtonThemeMode( value: themeMode, onChanged: (value) { if (value ! null) { ref.read(themeModeProvider.notifier).state value; } }, items: [ DropdownMenuItem( value: ThemeMode.light, child: Text(浅色模式), ), DropdownMenuItem( value: ThemeMode.dark, child: Text(深色模式), ), DropdownMenuItem( value: ThemeMode.system, child: Text(跟随系统), ), ], ); } } // 在 MaterialApp 中使用 class MyApp extends ConsumerWidget { override Widget build(BuildContext context, WidgetRef ref) { final themeMode ref.watch(themeModeProvider); return MaterialApp( themeMode: themeMode, theme: ThemeData.light(), darkTheme: ThemeData.dark(), home: HomePage(), ); } }五、最佳实践单一职责每个 Provider 只做一件事依赖注入通过 Provider 传递依赖便于测试自动释放使用 autoDispose 避免内存泄漏错误处理始终处理异步操作的错误状态状态是应用的脉搏Riverpod 让脉搏跳动得更有韵律。#flutter #riverpod #state-management #dart #architecture