【问题标题】:How to create multiple copies of a deeply nested immutable Object?如何创建深度嵌套的不可变对象的多个副本?
【发布时间】:2019-08-21 18:03:43
【问题描述】:

我正在尝试使用 javascript 从 firebase/firestore 获取数据,所以我创建了一个函数,在其中获取我的产品集合并通过 setState() 方法将此数据传递给 reactjs state.products

我的目标是将这些产品传递到我的反应状态,但同时保留原始数据而不是通过操作来更改它。我知道在 JavaScript 中,每当我们将对象分配给变量时,我们实际上是将它们作为引用传递而不是复制它们,所以这就是为什么我使用 3 点(扩展语法) 来复制 firestore将数据复制到 tempProducts[] 中的方法与将其复制到处女 [] 中的方法相同

getData = () => {
    let tempProducts = [];
    let virgins = [];
    db.collection("products")
      .get()
      .then(querySnapshot => {
        querySnapshot.forEach(item => {
          const singleItem = { ...item.data() };
          virgins = [...virgins, singleItem];
          tempProducts = [...tempProducts, singleItem];
        });
        tempProducts[0].inCart = true;
        this.setState(
          () => {
            return { products: tempProducts };
          },
          () => {
            console.log(
              "this.state.products[0].inCart: " + this.state.products[0].inCart
            );
            console.log("tempProducts[0].inCart: " + tempProducts[0].inCart);
            console.log("virgins[0].inCart: " + virgins[0].inCart);
          }
        );
      });
  };

然后在componentDidMount中调用这个方法

componentDidMount() {
    this.getData();
  }

所以我在控制台记录 tempProducts 值和 state.products 值时将 tempProducts 中的第一个产品 inCart 值更改为 true当我控制台记录处女值但我没有。 我还应该提到,所有 inCart 值在 firestore 数据中都是错误的

【问题讨论】:

  • 扩展运算符进行浅复制,这意味着在操作过程中深层引用仍将保持不变。如果您想破坏所有引用并获得一个真实的、未引用的副本,则需要完全克隆该对象。
  • 扩展语法不会克隆嵌套的属性或值。因此,您只是在创建新数组,其中包含相同的 Object 引用。
  • 其他可能的重复(专门处理修改不可变数组)Correct modification of state arrays in ReactJS
  • 所以我知道我也应该在 singleItem 对象旁边使用扩展运算符,就像virgins = [...virgins, {...singleItem}]; 对吗?

标签: javascript reactjs firebase google-cloud-firestore


【解决方案1】:

我通过将原始 firestore 数据传递给处女 [] 而不是 singleItem 解决了这个问题,因为它是 tempProducts[] 引用的对象,就像 virgins = [...virgins, item.data()]; 一样,如果我复制了 singleItem 对象而不是像这样引用它,它也可以工作所以virgins = [...virgins, { ...singleItem }]; 请记住,我不知道这个解决方案是否真的有效(不是“内存浪费”)。

【讨论】:

    猜你喜欢
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 2021-08-31
    • 2020-04-09
    • 2012-01-02
    • 1970-01-01
    相关资源
    最近更新 更多