如何将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
相关产品推荐
相关产品推荐

