在 Flutter 中更新对象实例属性的最佳实践是什么?该实例嵌套在提供程序类的映射内,如下所示

Ram*_*ran 5 provider dart flutter

我是 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,
  });
}
Run Code Online (Sandbox Code Playgroud)

Item另一个类使用,该类在映射中Cart存储 s 列表,并且它有一个减少数量的方法,如下所示:ItemremoveSingleItem

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();
  }
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,购物车是一个提供者。我的问题是为什么我们要创建一个新的Itemusing _items.update?而不是在使属性成为非最终属性后直接修改 Item 对象的内容:

_items[productId]!.数量 -= 1;

这会不会给状态管理带来什么问题呢?因为在演示应用程序中,即使我们不创建整个新的 Item 对象,订单屏幕(新的 Scaffold)似乎也会正确更新。

该课程的评论部分不再活跃,因此请在此处询问。感谢帮助!

lep*_*sch 3

可变数据类最危险的事情是它可以从代码的每个部分发生变化,而不仅仅是模型提供者。

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

  • 不可变数据类的构造函数为const,Flutter进一步优化了const对象;
  • 该框架可以有效地检测状态变化,因为唯一需要的比较是检查对象引用是否已更改;
  • 处理数据变得更安全,因为在不可预测的地方不会产生副作用或突变;

这就是为什么一堆类具有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,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,从现有实例创建新实例要容易得多:

  _items.update(
      productId,
      (existingCartItem) => existingCartItem.copyWith(
            quantity: existingCartItem.quantity - 1,
          ));

Run Code Online (Sandbox Code Playgroud)