Flutter中调用List.remove(element)无法删除列表对应元素问题排查
问题产生原因
- Dart默认采用引用相等判断对象是否相同:你调用
remove方法时传入的CartItem(product: widget.product)是全新创建的实例,和之前add方法存入_items列表的CartItem实例不是同一个内存对象,List.remove()方法找不到匹配项,因此无法删除,列表长度不变。 - 额外隐患:你当前
add方法中遍历_items给同一个cartMap赋值会不断覆盖字段,最终cartMap仅会存储列表最后一个商品的信息,后续同步到Firestore的内容会出错。
修复方案
1. 解决列表无法删除问题(二选一即可,推荐第一种)
方案A:重写CartItem的相等判断逻辑
在CartItem类中重写==运算符和hashCode,按商品唯一标识(比如Product的id)判断两个实例是否相等,无需依赖内存引用:
class CartItem { final Product product; CartItem({required this.product}); @override bool operator ==(Object other) => identical(this, other) || other is CartItem && runtimeType == other.runtimeType && // 用Product的唯一ID作为相等判断依据 (product as Product).id == (other.product as Product).id; @override int get hashCode => (product as Product).id.hashCode; }
方案B:修改删除逻辑按字段匹配删除
不需要修改CartItem类,直接在remove方法中用removeWhere按商品字段匹配删除:
void remove(BuildContext context, CartItem item) { // 按商品ID匹配删除,不依赖实例引用 _items.removeWhere((element) => (element.product as Product).id == (item.product as Product).id ); // 后续原有Firestore同步逻辑保持不变 AuthService authService = Provider.of<AuthService>(context, listen: false); Map<String, dynamic> cartMap = { 'id': (item.product as Product).id, 'title': (item.product as Product).title, 'name': (item.product as Product).name }; _instance = FirebaseFirestore.instance; _instance!.collection('cart').doc(authService.getCurrentUser()).update({ 'cartProduct': FieldValue.arrayRemove([cartMap]), }).then((value) { print(_items.length); notifyListeners(); }); }
2. 修复add方法的Firestore同步bug
删除原有遍历逻辑,直接为当前新增的商品生成Map,避免字段覆盖问题:
void add(BuildContext context, CartItem item) { _items.add(item); AuthService authService = Provider.of<AuthService>(context, listen: false); // 直接为当前新增商品构造Map,无需遍历整个列表 Map<String, dynamic> cartMap = { 'id': (item.product as Product).id, 'title': (item.product as Product).title, 'name': (item.product as Product).name }; _instance = FirebaseFirestore.instance; _instance! .collection('cart') .doc(authService.getCurrentUser()) .update({ 'cartProduct': FieldValue.arrayUnion([cartMap]) }).then((value) { print(_items.length); notifyListeners(); }); }
内容的提问来源于stack exchange,提问作者Ricky Kim
相关产品推荐
相关产品推荐

