Flutter Dio请求API仅显示加载框 页面不渲染返回数据
Flutter Dio请求成功但FutureBuilder一直显示加载组件排查方案
核心问题集中在Future传参错误、状态判断逻辑不全、数据解析抛错、请求方法未正确返回结果四类,按以下顺序逐一排查即可解决:
1. 修正FutureBuilder的Future传参方式
- 禁止在build方法内直接调用请求方法给future赋值,每次UI重绘都会触发新的请求,永远拿不到稳定的请求完成状态
错误写法参考:
正确写法:在@override Widget build(BuildContext context) { return FutureBuilder( // 错误:build触发时会反复执行fetchData,生成新的Future实例 future: fetchApiData(), builder: (context, snapshot) { // 组件逻辑 } ); }initState生命周期内提前发起请求,将结果存在State的成员变量中传入FutureBuilderlate Future<YourDataModel> _dataFuture; @override void initState() { super.initState(); // 整个页面生命周期内只执行一次请求 _dataFuture = fetchApiData(); } @override Widget build(BuildContext context) { return FutureBuilder<YourDataModel>( future: _dataFuture, builder: (context, snapshot) { // 状态判断逻辑 } ); }
2. 补全Snapshot的状态判断逻辑
不要仅判断waiting状态就显示加载组件,必须按「先判错、再判完成、最后兜底加载」的顺序写判断逻辑,否则解析异常、数据为空的场景会一直卡在加载态:
builder: (context, snapshot) { // 优先捕获错误,直接展示错误信息,不要卡加载 if (snapshot.hasError) { // 必须打印错误栈,90%的解析异常都能在这里定位 print('请求/解析异常: ${snapshot.error}\n栈信息: ${snapshot.stackTrace}'); return Center(child: Text('加载失败: ${snapshot.error}')); } // 判断请求是否执行完成 if (snapshot.connectionState == ConnectionState.done) { // 校验数据非空后渲染UI if (snapshot.hasData) { final model = snapshot.data!; return Center(child: Text('Value字段内容:${model.value}')); } return const Center(child: Text('返回数据为空')); } // 未完成状态兜底显示加载组件 return const Center(child: CircularProgressIndicator()); }
注意:不要单独判断
ConnectionState.waiting显示加载,ConnectionState.none、ConnectionState.active状态下如果没有匹配分支,会持续显示加载组件。
3. 排查数据解析的隐式异常
控制台能打印原始接口返回数据,大概率是fromJson解析过程中抛出了未捕获的类型/字段匹配错误,导致Future进入异常状态但你之前没做错误捕获:
- 核对模型类字段和JSON返回的键名完全匹配,大小写、下划线命名不能有偏差,比如JSON返回
value你写了Value就会取值失败 - 字段类型做兼容处理,禁止直接强转,比如接口返回int类型的Value,你模型里定义成String直接强转就会抛异常
安全的fromJson写法参考:factory YourDataModel.fromJson(Map<String, dynamic> json) { return YourDataModel( // 做类型兜底,避免强转报错 value: json['Value']?.toString() ?? '', ); }
4. 检查Dio请求方法是否正确返回解析结果
很多人写请求时拿到响应只做了打印,没有把解析后的模型返回,会导致Future一直处于等待状态:
错误写法参考:
Future<YourDataModel> fetchApiData() async { final resp = await dio.get('你的接口地址'); print(resp.data); // 控制台能正常打印数据 // 错误:没有return解析结果,Future永远不会进入完成状态 YourDataModel.fromJson(resp.data); }
正确写法必须返回解析后的实例:
Future<YourDataModel> fetchApiData() async { final resp = await dio.get('你的接口地址'); print(resp.data); // 主动return解析结果,Future才能正常进入done状态 return YourDataModel.fromJson(resp.data); }
内容的提问来源于stack exchange,提问作者SaDev
相关产品推荐
相关产品推荐

