Flutter中setState调用后列表未更新问题排查
问题根因
你的代码有4个核心问题导致setState不生效、匹配逻辑失效:
- HTTP响应状态码判断错误:直接拿
http.Response类型的响应对象和整数200做相等判断,结果永远为false,后续所有setState、数据解析逻辑根本不会执行。 - 网络请求调用位置错误:把
fetch()方法直接写在build渲染方法里,每次UI重绘都会触发新的网络请求,形成无限请求循环,上一次请求还没返回就被新请求打断,数据永远无法正常赋值到状态变量。 - IMEI匹配逻辑错误:硬编码取
compaints[2]、found[1],本质是取列表第3、第2个整条元素,不是取元素内的IMEI字段;且只对比两个固定位置的元素,没有做全量数据遍历匹配,就算接口请求成功也无法得到正确的匹配结果。 - 冗余逻辑问题:在
setState回调内部嵌套判断mounted、二次调用setState,属于无效写法,还可能导致不必要的重绘异常。
修复方案
- 将网络请求初始化逻辑移到
initState生命周期中,保证页面加载时只执行一次请求,避免无限循环。 - 修正状态码判断逻辑,通过
response.statusCode获取HTTP响应状态码做校验。 - 解析接口返回数据后,先提取所有条目的IMEI字段,通过集合求交集的方式一次性得到所有匹配的IMEI值,不要硬编码固定索引。
- 所有状态变量的赋值操作统一放在单次
setState回调中执行,减少不必要的UI重绘。 - 补充请求异常捕获逻辑,避免接口报错时页面崩溃。
修复后完整代码
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { List compaints = []; List found = []; List match = []; @override void initState() { super.initState(); fetchData(); } Future<void> fetchData() async { try { final responseOne = await http.get(Uri.parse("https://script.google.com/macros/s/AKfycbxi9kN6NWvoFjkQZE1OVJDPpWmQeYk0V5hNfRKqXS19wjz86SYq_FoQ51fjNQY22bN4/exec")); final responseTwo = await http.get(Uri.parse("https://script.google.com/macros/s/AKfycbx20kfm1g4Hno9DzO1uccmLgmuIQBkXQcA9tnhcup873TsEMEy9ejszCluhf4FzW-YJqQ/exec")); if (responseOne.statusCode == 200 && responseTwo.statusCode == 200) { final compaintsList = jsonDecode(responseOne.body) as List; final foundList = jsonDecode(responseTwo.body) as List; // 注意:这里的'imei'替换成你接口实际返回的IMEI字段名 final compaintsImeiSet = compaintsList.map((e) => e['imei'].toString()).toSet(); final foundImeiSet = foundList.map((e) => e['imei'].toString()).toSet(); final matchedList = compaintsImeiSet.intersection(foundImeiSet).toList(); if (mounted) { setState(() { compaints = compaintsList; found = foundList; match = matchedList; }); } } } catch (err) { debugPrint('数据拉取异常: $err'); } } @override Widget build(BuildContext context) { return Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: [ Text(compaints.length.toString()), const SizedBox(height: 20), Text(found.length.toString()), const SizedBox(height: 20), Text('匹配IMEI数量: ${match.length}'), ], ), ); } }
提示:如果你的接口返回的IMEI字段名不是
imei,把代码里e['imei']的key替换成实际字段名即可正常匹配。
内容的提问来源于stack exchange,提问作者Asif Shaik
相关产品推荐
相关产品推荐

