Flutter调用forEach报'(dynamic)=>Null'非(String,dynamic)=>void子类型错误如何解决
问题原因
- 核心触发原因:
json.decode(result.body)返回的结果实际为Map<String, dynamic>类型,而非你预期的列表类型。Map的forEach方法要求传入的回调必须接收两个参数(键、值),但你只传入了接收单个参数的回调,因此触发类型不匹配报错。 - 隐含问题:你在forEach循环内反复调用
setState更新列表,会触发多次不必要的UI重绘;如果异步执行过程中当前组件已经被销毁,直接调用setState还会抛出上下文不存在的异常。
修复方案
第一步:调整home.dart代码逻辑
请先根据后端接口实际返回结构调整取值逻辑,下方代码默认适配两种常见返回场景:
Future<List<Chat>> _getAllChat() async { List<Chat> _List = []; var result = await _chatService.getAllChat(); if (result == null) return _List; final decodeRes = json.decode(result.body); List Chats; // 场景1:接口直接返回聊天列表数组,取消注释下方代码,注释场景2代码 // Chats = decodeRes as List; // 场景2:接口返回带业务状态的外层Map,列表存放在data字段下,根据实际字段名修改即可 Chats = decodeRes['data'] as List; // 批量转换数据后再一次性更新UI,提升性能 _List = Chats.map((achat) { var model = Chat(); model.id = achat['id'] as int; model.msg = achat['msg'] as String; // 其余字段按需赋值即可 return model; }).toList(); // 加mounted判断,避免组件销毁后调用setState报错 if (mounted) { setState(() {}); } return _List; }
(可选优化)为Chat类新增fromJson构造方法
后续序列化数据时代码更简洁易维护,修改Chat.dart如下:
class Chat { late int id; late int userId; late int user2Id; late String msg; Chat.fromJson(Map<String, dynamic> json) { id = json['id'] as int; userId = json['userId'] as int; user2Id = json['user2Id'] as int; msg = json['msg'] as String; } }
优化后列表转换逻辑可简化为一行:
_List = Chats.map((e) => Chat.fromJson(e as Map<String, dynamic>)).toList();
内容的提问来源于stack exchange,提问作者Abdallah Sakre
相关产品推荐
相关产品推荐

