You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:47:57