代码之家  ›  专栏  ›  技术社区  ›  user3808307

如果我使用扩展运算符,为什么状态会发生变化?

  •  0
  • user3808307  · 技术社区  · 6 年前

    onVote = (dir, index) => {        
        console.log(this.state)
    
        const products = [...this.state.products]           
        products[index].votes = dir ? products[index].votes + 1 : products[index].votes - 1
    
        console.log(this.state.products[index].votes)
        // this.setState({products})
      };
    

    https://jsfiddle.net/hkL3wug7/2/

    但是,即使我没有设置状态,控制台日志显示,每当我单击加号和减号时,状态都会改变。

    我做了与本文相同的事情 https://medium.com/@giltayar/immutably-setting-a-value-in-a-js-array-or-how-an-array-is-also-an-object-55337f4d6702

    const newState = [...state] // clone the array
          newState[action.index].done = true
          return newState
    

    据我所知

    0 回复  |  直到 6 年前
        1
  •  6
  •   smashed-potatoes    6 年前

    正如@Carcigenicate所提到的,您已经创建了一个数组的浅拷贝,这意味着您有一个指向原始数组中相同对象的新数组。

    为了避免对原始对象进行变异,还需要创建一个要变异的对象的副本,例如:

    // Shallow copy of the array
    const products = [...this.state.products];
    
    // Shallow copy of the object within the array
    const updatedProduct = { ...products[index] };
    
    // Update the copy of the object
    updatedProduct.votes = dir ? updatedProduct.votes + 1 : updatedProduct.votes - 1;
    
    // Replace the object with the updated copy
    products[index] = updatedProduct;
    
        2
  •  2
  •   dangerginger    6 年前

    Object 通过引用传递的。所以即使你的局部变量 products this.state.products ,它们都包含对相同的引用 对象

    要实现您正在尝试的操作,您必须在中克隆对象 本州产品 Object.assign 把你的 const products = [...this.state.products] 有:

    const products = [
        Object.assign({}, this.state.products.Orange),
        Object.assign({}, this.state.products.Apples),
        Object.assign({}, this.state.products.Bananas)
    ]