如何创建深层嵌套的不可变对象的多个副本?

时间:2019-08-21 18:03:43

标签: javascript reactjs firebase google-cloud-firestore

我正尝试使用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 ,它使我一切正常,但我期望得到假当我控制台记录处女值但我没有时我还应该提到,firestore数据中的所有inCart值均为假

1 个答案:

答案 0 :(得分:0)

我通过将原始Firestore数据传递给virgins []而不是singleItem来解决了该问题,因为它是tempProducts []引用的对象,因此virgins = [...virgins, item.data()];也适用,如果我复制singleItem对象而不是引用就像virgins = [...virgins, { ...singleItem }]; 这样,请紧记我不知道这种解决方案实际上是否有效(不是“内存浪费”)。