我是 Flutter 新手,正在学习 Udemy 上的课程。我有一个名为 Item 的模型,它具有
final
属性,如图所示:
class Item {
final String id;
final String title;
final int quantity;
final double price;
Item({
required this.id,
required this.title,
required this.quantity,
required this.price,
});
}
Item
由另一个类Cart
使用,它在地图中存储Item
的列表,并且它有一个removeSingleItem
方法可以减少数量,如下所示:
class Cart with ChangeNotifier {
Map<String, Item> _items = {};
void removeSingleItem(String productId) {
if (!_items.containsKey(productId)) {
return;
}
if (_items[productId]!.quantity > 1) {
_items.update(
productId,
(existingCartItem) => Item(
id: existingCartItem.id,
price: existingCartItem.price,
quantity: existingCartItem.quantity - 1,
title: existingCartItem.title,
));
} else {
_items.remove(productId);
}
notifyListeners();
}
我们可以看到购物车是一个提供商。
为什么我们要使用
Item
创建一个新的 _items.update
?而不是在将属性设置为非最终属性后直接修改 Item 对象的内容:
_items[产品Id]!.数量 -= 1;
这会导致状态管理出现问题吗?因为在演示应用程序中,即使我们不创建整个新的 Item 对象,订单屏幕(新的 Scaffold)似乎也会正确更新。
可变数据类最危险的事情是,它可以从代码的每个部分发生变化,而不仅仅是模型提供者。
这些是使数据不可变的一些方面:
这就是为什么一堆类具有
copyWith
方法来仅改变一个属性,但它返回一个新的对象实例。
因此,使
Item
不可变并创建一个 copyWith
方法,如以下代码片段所示:
class Item {
final String id;
final double price;
final double quantity;
final String title;
const Item({
required this.id,
required this.price,
required this.quantity,
required this.title,
});
Item copyWith({
String? id,
double? price,
double? quantity,
String? title,
}) {
return Item(
id: id ?? this.id,
price: price ?? this.price,
quantity: quantity ?? this.quantity,
title: title ?? this.title,
);
}
}
通过这种方式从现有实例创建新实例要容易得多:
_items.update(
productId,
(existingCartItem) => existingCartItem.copyWith(
quantity: existingCartItem.quantity - 1,
));