两次导航至含Dropdown的页面触发重复值错误,求解决方案
问题分析与解决方案
核心错误原因
这个问题的本质是自定义类的相等性判断不匹配,加上页面返回后的状态与新数据不同步:
- Dart中自定义类默认使用引用相等,返回页面后重新请求API得到的
EventCategory是新实例,即使categoryId和名称完全相同,旧的_selectedCategory(之前页面的实例)和新列表中的对象用==比较会返回false,导致Dropdown认为没有匹配的选项,触发断言错误。 - 页面返回后,父组件没有将旧的选中状态与新获取的分类列表同步,导致选中项不在新列表的匹配范围内。
解决方案
1. 重写EventCategory的相等性判断
修改EventCategory类,让Dart根据categoryId判断两个对象是否相等,而不是引用:
class EventCategory { final String categoryId; final String? name; EventCategory({required this.categoryId, this.name}); // 重写==运算符,基于categoryId判断相等 @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is EventCategory && other.categoryId == categoryId; } // 必须同时重写hashCode,确保集合操作正确性 @override int get hashCode => categoryId.hashCode; }
2. 页面返回时同步选中状态
在父组件获取新分类列表的逻辑中,根据旧选中项的categoryId在新列表中找到对应实例,更新_selectedCategory:
else if (state is CategoryListSuccess) { if (_selectedCategory != null) { // 在新分类列表中匹配相同categoryId的项 final matchedCategory = state.categories.firstWhere( (cat) => cat.categoryId == _selectedCategory!.categoryId, // 如果找不到(比如分类被删除),默认选中第一个 orElse: () => state.categories.first, ); _selectedCategory = matchedCategory; } else { _selectedCategory = state.categories.first; } setState(() {}); // 强制更新UI,同步状态 }
3. 排查重复分类ID
检查API返回的categories列表,确保没有categoryId重复的项——如果存在重复,Dropdown会检测到多个匹配项,同样触发该错误。
内容的提问来源于stack exchange,提问作者Demir
相关产品推荐
相关产品推荐

