Flutter发起HTTP请求时出现无限请求循环问题求助
Flutter中GET请求无限循环问题的定位与解决
核心问题分析
- FutureBuilder误用:你的
FutureBuilder直接传入kriptoGetir(),每次Widget重建时都会调用该方法发起新请求。而kriptoGetir()内的setState会触发Widget重建,形成请求→setState→重建→再次请求的无限循环。 - 状态变量未正确更新:
kriptoGetir()中的setState(() { kriptoList; });未将请求到的列表赋值给类成员变量,导致状态未实际更新,Widget无法复用已有数据,只能反复发起请求。 - Timer逻辑无效:你在
initState中初始化了kriptoGet并通过Timer更新它,但FutureBuilder并未使用这个变量,而是直接调用方法,导致Timer的更新逻辑完全失效。
修复步骤
1. 定义类成员状态变量
添加用于存储数据和管理Timer的成员变量:
List<KriptoModel> _kriptoList = []; Timer? _updateTimer; Future? _kriptoGet;
2. 修正请求方法kriptoGetir
更新setState逻辑,将请求结果正确赋值给类成员变量:
Future<List<KriptoModel>> kriptoGetir() async { final response = await http.get(Uri.parse(url)); final durum = response.statusCode; print(durum.toString()); if (durum == 200) { var jsonRes = jsonDecode(response.body); List<KriptoModel> kriptoList = []; for (var i = 0; i < jsonRes.length; i++) { kriptoList.add(KriptoModel.fromJson(jsonRes[i])); } setState(() { _kriptoList = kriptoList; // 正确更新状态变量 }); return kriptoList; } else { throw Exception('istek başarısız'); } }
3. 修正initState与Timer逻辑
确保Timer更新状态时触发正确重建,同时在页面销毁时取消Timer避免内存泄漏:
@override void initState() { super.initState(); _kriptoGet = kriptoGetir(); _updateTimer = Timer.periodic(const Duration(seconds: 60), (timer) { setState(() { _kriptoGet = kriptoGetir(); // 更新Future变量并触发重建 }); }); } @override void dispose() { _updateTimer?.cancel(); // 页面销毁时取消Timer super.dispose(); }
4. 修正FutureBuilder使用方式
使用初始化好的_kriptoGet变量,而非直接调用请求方法:
FutureBuilder( future: _kriptoGet, builder: (context, veri) { if (veri.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (veri.hasError) { return Center(child: Text('请求失败: ${veri.error}')); } else if (!veri.hasData || _kriptoList.isEmpty) { return const Center(child: Text('无数据')); } else { return Container( width: MediaQuery.of(context).size.width, height: 70, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: const Color.fromARGB(255, 13, 2, 31), ), child: ListTile( leading: Image.network(_kriptoList[index].image, width: 35), title: Text( _kriptoList[index].id.toString(), style: const TextStyle(color: Colors.white), ), subtitle: Text( '\$ ${_kriptoList[index].currentPrice}', style: const TextStyle(color: Colors.white, fontSize: 14), ), trailing: methodDegisimKontrol( _kriptoList[index].marketCapChangePercentage24h), onTap: () { // Navigator逻辑 }, ), ); } }, );
额外注意事项
- 模型类中
id字段赋值为json['name'],如果实际需要接口返回的id字段,需修改为id: json['id']。 - 避免在
build方法中直接调用异步方法,所有异步请求应在initState、didChangeDependencies或事件回调中触发。 - 频繁请求接口可能触发API限流,建议根据接口文档调整请求间隔。
内容的提问来源于stack exchange,提问作者Yusuf Barulay
相关产品推荐
相关产品推荐

