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

如何在Flutter Riverpod中结合ref watch与AsyncValue实现加载状态?

问题分析

你的代码中,点击按钮更新paramProvider后,futureProvider虽会重新执行异步请求,但Riverpod的FutureProvider默认会保留旧数据并在后台刷新,因此when方法的loading回调不会触发,而是直接显示旧数据直到新数据返回,这就是看不到加载动画的原因。

解决方案

方案一:点击按钮时手动失效FutureProvider

在按钮的点击事件中,更新参数后主动调用ref.invalidate(futureProvider),强制futureProvider重新初始化并进入加载状态:

ElevatedButton(
  onPressed: () {
    ref.read(paramProvider.notifier).state = 'new value';
    ref.invalidate(futureProvider); // 触发provider重新加载,显示加载动画
  },
  child: const Text('pretend update'),
)

方案二:利用AsyncValue的isLoading属性判断加载状态

如果希望保留旧数据的同时显示加载动画,可以在data回调中检查isLoading状态:

ref.watch(futureProvider).when(
  data: (data) {
    // 后台加载新数据时,显示加载动画
    if (ref.watch(futureProvider).isLoading) {
      return const CircularProgressIndicator();
    }
    return Column(
      children: [
        ElevatedButton(
          onPressed: () => ref.read(paramProvider.notifier).state = 'new value',
          child: const Text('pretend update'),
        ),
        Text(data)
      ],
    );
  },
  error: (_,__) => const Text('something went wrong'),
  loading: () => const CircularProgressIndicator(),
)

方案三:自定义Provider逻辑强制触发加载

修改futureProvider的实现,通过ref.listen监听参数变化,主动触发重新加载:

final futureProvider = FutureProvider.autoDispose<String>((ref) async {
  // 监听参数变化,主动刷新provider
  ref.listen<String>(paramProvider, (_, __) {
    ref.refresh(futureProvider);
  });
  String parameter = ref.watch(paramProvider);
  return pretendApiCall(parameter);
});

内容的提问来源于stack exchange,提问作者nAndroid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:39:22