Flutter中使用Riverpod AsyncNotifier实现API成功后显示Snackbar
解决Riverpod AsyncNotifier中API请求后显示Snackbar的问题
1. 重构代码为AsyncNotifier结构
原来的TableServices只是一个无状态的服务类,无法追踪API请求的状态变化。我们需要将其重构为AsyncNotifier,利用它自带的AsyncValue来管理异步请求的加载、成功、失败状态:
class TableNotifier extends AsyncNotifier<void> { // 初始化无状态 @override FutureOr<void> build() => null; Future<void> themMon(AddMealToTableRequest item) async { // 用AsyncValue.guard自动处理异步状态,省去手动设置loading/error的代码 state = await AsyncValue.guard(() async { final response = await addMealToTable(item); if (response.ErrorMsg.isNotEmpty) { throw Exception(response.ErrorMsg); } }); } } // 声明对应的AsyncNotifierProvider,供UI层调用和监听 final tableNotifierProvider = AsyncNotifierProvider<TableNotifier, void>(() => TableNotifier());
2. 在UI层监听状态并显示Snackbar
在需要触发添加菜品操作的页面,通过ref.listen监听tableNotifierProvider的状态变化,根据AsyncValue的不同状态(成功/失败)显示对应Snackbar:
class MealAddPage extends ConsumerWidget { const MealAddPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { // 监听AsyncNotifier的状态变更 ref.listen<AsyncValue<void>>(tableNotifierProvider, (previous, next) { next.whenOrNull( // 请求成功时显示成功提示 data: (_) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('菜品添加成功')), ); }, // 请求失败时显示错误提示 error: (error, _) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('添加失败:${error.toString()}')), ); }, ); }); return Scaffold( body: Center( child: ElevatedButton( onPressed: () { // 调用Notifier中的添加菜品方法 ref.read(tableNotifierProvider.notifier).themMon(AddMealToTableRequest(...)); }, child: const Text('添加菜品'), ), ), ); } }
关键说明
AsyncNotifier的核心是AsyncValue,它封装了异步操作的三种状态:loading、data、error,无需手动维护状态切换逻辑。- 不要在Notifier内部直接调用UI相关的方法(比如
ScaffoldMessenger),保持逻辑层与UI层解耦,状态变化由UI层监听处理才符合Riverpod的设计思想。 - 如果需要显示加载状态,可以在
next.when中补充loading分支,比如显示CircularProgressIndicator。
内容的提问来源于stack exchange,提问作者Dat Minh
相关产品推荐
相关产品推荐

