我是新手,正在学习一门关于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使用,它在 map 中存储一个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();
  }

正如我们所看到的,购物车是一个提供者.我的问题是,为什么我们要用_items.update来创建一个新的Item?在将属性设置为非最终属性后,不像这样直接修改Item对象的内容:

_Items[ProductID]!.Quantity-=1;

这会不会给国家管理带来问题?因为在演示应用程序中,即使我们没有创建一个完整的新Item对象,Orders屏幕(新的Scaffold)似乎也会正确更新.

课程的 comments 部分不再处于活动状态,因此请在此处提问.谢谢你的帮助!

推荐答案

可变数据类最危险的地方是,它可能会在代码的每个部分发生变化,而不仅仅是模型提供程序.

以下是使数据不可变的一些方面:

  • 一个不可变的数据类将构造函数作为const,Ffltter进一步优化了const对象;
  • 该框架能够有效地检测状态变化,因为所需要的唯一比较是判断对象引用是否改变;
  • 处理数据变得更安全,因为在不可预测的地方没有副作用或Mutations ;

这就是为什么许多类使用copyWidth方法只改变一个属性,但它返回一个新的对象实例.

因此,将Item设置为不可变的,并创建一个copyWidth方法,如下所示:

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.copyWidth(
            quantity: existingCartItem.quantity - 1,
          ));

Flutter相关问答推荐

如何使用底部导航栏修复此导航问题

如何将Xpriter代码页更改为代码页27?

使用GO_ROUTER在模式内导航

与FTPS连接时出现Flutter FTPConnect HandshakeException错误

有没有可能不在BlocBuilder中重新构建内容?

如何在Flutter Webview包中触发基于URL导航的事件

Flutter:我的应用程序是否需要包含退款购买?

Flutter http 请求获取 null

我无法找到修复此错误的位置,指出无法使用静态访问来访问实例成员

Dart:未捕获错误:RangeError(索引):索引超出范围:索引应小于 7:7

Flutter开发中,如何通过'nfc_manager'插件在Android设备上避免默认的New Tag Scanned弹出窗口?

来自服务器的数据未分配给变量

Flutter - 如何将按钮对齐到行的右侧

如何在两个不同的路由(屏幕)之间正确设置 BlocProvider?

按下 Command+W 时关闭窗口

改变步进器的线条 colored颜色 Flutter

CircleAvatar 在 ListTile 中领先

如何判断 text.contains() 是否包含多个值

在Flutter 中将数字转换为印度文字样式

Flutter Firebase 可以在真实设备上运行,而不是在 Android 模拟器上运行