Flutter如何实现一次API拉取数据供多个页面使用
Flutter 单次请求用户数据全局复用实现方案
核心思路是将请求到的用户数据存储在全局可访问的存储层,请求前先判断是否已有缓存,存在缓存直接返回,无缓存才发起接口请求,同时加锁避免并行场景下重复发起相同请求。
方案1:全局单例实现(最轻量,无需引入第三方库)
适合小型项目,无需额外依赖即可快速实现:
- 首先定义单例类,封装用户数据存储、请求逻辑:
// 你自己定义的用户数据模型 class UserModel { final String userId; final String nickname; // 其他字段... UserModel.fromJson(Map<String, dynamic> json) : userId = json['user_id'], nickname = json['nickname']; } class UserInfoSingleton { // 私有构造方法,禁止外部实例化 UserInfoSingleton._internal(); static final UserInfoSingleton _instance = UserInfoSingleton._internal(); factory UserInfoSingleton() => _instance; UserModel? cachedUserInfo; bool _isRequesting = false; // 防重复请求标记 // 全局统一调用的获取用户信息方法 Future<UserModel?> fetchUserInfo({bool forceRefresh = false}) async { // 非强制刷新且已有缓存直接返回 if (!forceRefresh && cachedUserInfo != null) return cachedUserInfo; // 已有正在进行的请求,等待请求完成后返回结果 if (_isRequesting) { await Future.doWhile(() => Future.delayed(const Duration(milliseconds: 100), () => _isRequesting)); return cachedUserInfo; } try { _isRequesting = true; // 替换为你自己的接口请求逻辑 final response = await Dio().get('/api/user/detail'); cachedUserInfo = UserModel.fromJson(response.data); return cachedUserInfo; } catch (e) { rethrow; } finally { _isRequesting = false; } } // 退出登录时调用清空缓存 void clearCache() { cachedUserInfo = null; } }
- 任意页面需要用户数据时,直接调用
UserInfoSingleton().fetchUserInfo()即可,首次调用会发起请求,后续所有调用直接返回缓存数据。
方案2:状态管理工具实现(适合中大型项目,需要响应式更新)
如果你项目中已经使用了Provider、Riverpod、Bloc、GetX等状态管理工具,直接用全局状态存储即可,逻辑和单例一致:
- 在全局作用域定义用户数据相关的状态
- 封装请求方法时加缓存判断、防重复请求逻辑
- 所有页面直接读取/监听全局状态中的用户数据即可
以Riverpod为例的极简实现:
final userInfoProvider = FutureProvider<UserModel?>((ref) async { // Riverpod默认会缓存Future返回结果,只要provider不被销毁就不会重复请求 final response = await Dio().get('/api/user/detail'); return UserModel.fromJson(response.data); });
页面直接读取该provider即可,框架自动处理缓存复用。
方案3:InheritedWidget实现(原生方案,适合上层向下共享数据)
如果不想用单例也不想引入状态管理,可以在根路由或者上层路由中嵌套InheritedWidget存储用户数据,首次进入页面时发起请求存入组件,所有子页面都可以通过context直接获取数据,适合不需要频繁更新用户数据的场景。
注意事项
- 遇到用户信息修改、切换账号等场景,可以调用方法时传入
forceRefresh: true跳过缓存强制拉取最新数据 - 用户退出登录时必须清空用户缓存,避免出现不同账号数据串用的问题
- 必须加防重复请求标记,避免多个页面同时调用接口时触发多次相同请求
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

