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

如何将Riverpod中Future Provider的结果保存到新Provider供全局使用?

问题描述

我有如下API调用类GetSinglesApi:

class GetSinglesApi{

  Future<List<SingleModel>?> getSinglesApi() async{


    String token = 'retrtert';
    final uri = Uri.https(getBaseUrl(), PEOPLE_TABLE_ID);

    final response = await http.get(uri, headers: {
      HttpHeaders.authorizationHeader: "Bearer $token",
      "Content-Type": "application/json",
      'accept': 'text/plain'
    });


    var data = jsonDecode(response.body);

    checkStatusCode(response.statusCode, data);

    try {

      SinglesResponse singlesResponse = SinglesResponse.fromJson(data);

      print("Singles response lengeth: ${singlesResponse.records?.length}");

      return singlesResponse.records;

    } catch (e) {
        print('ERROR RESADIN JSON: ${e}');
    };

    }

  }

同时我使用Flutter的Riverpod实现该API调用,已定义如下两个Provider:

final getSinglesApiProvider = Provider.autoDispose<GetSinglesApi>(
    (ref) {
       return GetSinglesApi();
    }
);

final getSinglesResponseProvider = FutureProvider.autoDispose<List<SingleModel>?>((ref) async {
       return ref.watch(getSinglesApiProvider).getSinglesApi();
});

请问如何将getSinglesResponseProvider返回的SingleModel列表结果保存到新的Provider中,以便在应用的其他页面或组件中使用?


解决方案

可以通过Riverpod的状态类Provider(StateProvider或NotifierProvider)存储API返回的列表数据,以下是两种常用实现方式:

方式一:使用StateProvider(适合简单状态场景)

1. 定义存储列表的StateProvider

// 定义自动销毁的StateProvider,初始值为null
final singlesListProvider = StateProvider.autoDispose<List<SingleModel>?>((ref) => null);

2. 监听FutureProvider并更新状态

可以在页面的Consumer组件中监听getSinglesResponseProvider,当Future返回成功结果时更新状态:

Consumer(
  builder: (context, ref, child) {
    final singlesAsync = ref.watch(getSinglesResponseProvider);
    
    // 处理Future成功状态
    singlesAsync.whenData((singles) {
      if (singles != null) {
        ref.read(singlesListProvider.notifier).state = singles;
      }
    });

    // 处理加载、错误状态
    return singlesAsync.when(
      loading: () => const CircularProgressIndicator(),
      error: (err, stack) => Text('加载失败: $err'),
      data: (_) => // 页面UI内容
    );
  },
)

也可以在初始化逻辑中用ref.listen监听:

// 在页面initState或其他Provider的build方法中
ref.listen<AsyncValue<List<SingleModel>?>>(
  getSinglesResponseProvider,
  (previous, next) {
    next.whenData((singles) {
      ref.read(singlesListProvider.notifier).state = singles;
    });
  },
);

方式二:使用NotifierProvider(推荐,适合复杂状态管理)

如果后续需要对列表做更多操作(比如添加、删除元素),推荐用NotifierProvider:

1. 定义Notifier类和对应的Provider

class SinglesListNotifier extends AutoDisposeNotifier<List<SingleModel>?> {
  @override
  List<SingleModel>? build() {
    // 初始状态设为null
    return null;
  }

  // 自定义更新列表的方法
  void updateList(List<SingleModel>? newList) {
    state = newList;
  }

  // 可选:添加其他操作方法,比如新增元素
  void addSingle(SingleModel single) {
    final currentList = state ?? [];
    state = [...currentList, single];
  }
}

// 定义自动销毁的NotifierProvider
final singlesListProvider = AutoDisposeNotifierProvider<SinglesListNotifier, List<SingleModel>?>(
  SinglesListNotifier.new,
);

2. 监听FutureProvider并调用更新方法

ref.listen<AsyncValue<List<SingleModel>?>>(
  getSinglesResponseProvider,
  (previous, next) {
    next.whenData((singles) {
      ref.read(singlesListProvider.notifier).updateList(singles);
    });
  },
);

在其他页面/组件中使用存储的列表

无论用哪种方式,其他页面或组件只需通过ref.watch获取状态即可:

final singlesList = ref.watch(singlesListProvider);

// 根据列表状态渲染UI
if (singlesList == null) {
  return const Text('暂无数据');
} else {
  return ListView.builder(
    itemCount: singlesList.length,
    itemBuilder: (context, index) => ListTile(title: Text(singlesList[index].name)),
  );
}

注意事项

  • 若希望数据在页面销毁后保留,去掉Provider的autoDispose修饰符,改用普通的StateProvider或NotifierProvider
  • 记得处理Future的加载、错误状态,避免仅处理成功场景导致UI异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:35:18