Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用已编辑的对象属性返回新的重复使用状态_Javascript_Angular_Reactjs_Redux - Fatal编程技术网

Javascript 使用已编辑的对象属性返回新的重复使用状态

Javascript 使用已编辑的对象属性返回新的重复使用状态,javascript,angular,reactjs,redux,Javascript,Angular,Reactjs,Redux,当用户将相同的产品添加到购物车时,我尝试增加状态中相同产品的对象属性数量,而不是创建具有相同属性的新对象。因为状态不应该直接变异,所以我正在创建状态的副本,编辑数量,然后返回新数组。但我在尝试区分“[对象]”时出错。只允许使用数组和可重用项。这是正确的重做方式吗?下面是我在root reducer中添加到购物车的案例 export function rootReducer(state, action): IAppState { switch(action.type) { case A

当用户将相同的产品添加到购物车时,我尝试增加状态中相同产品的对象属性数量,而不是创建具有相同属性的新对象。因为状态不应该直接变异,所以我正在创建状态的副本,编辑数量,然后返回新数组。但我在尝试区分“[对象]”时出错。只允许使用数组和可重用项。这是正确的重做方式吗?下面是我在root reducer中添加到购物车的案例

export function rootReducer(state, action): IAppState {
  switch(action.type) {
    case ADD_PRODUCT:
        return Object.assign({}, state, {
            products: state.products.concat( Object.assign({}, action.payload) )
        });
    case REMOVE_PRODUCT:
        return Object.assign({}, state, {
            products: state.products.filter(t => t.id !== action.payload)
        });
    case REMOVE_ALL_PRODUCTS:
        return Object.assign({}, state, {
            products: []
        });
    case ADD_TO_CART:
        let duplicateItem = state.cartProducts.filter(item => item.id === action.payload.id);
        let duplicateIndex;
        if(duplicateItem.length) {
            for(var i = 0; i <= state.cartProducts.length - 1; i++){
                if(state.cartProducts[i].id === duplicateItem[0].id){
                    duplicateIndex = i;   
                }
            }
            let newArray = {...state.cartProducts};
            newArray[duplicateIndex].quantity = newArray[duplicateIndex].quantity === undefined ? 1 : newArray[duplicateIndex].quantity++;
            return Object.assign({}, state, {
                cartProducts: newArray
            });
        }
        return Object.assign({}, state, {
            cartProducts: state.cartProducts.concat( Object.assign({}, action.payload.product ) )
        });
    case REMOVE_FROM_CART:
        return Object.assign({}, state, {
            cartProducts: state.cartProducts.filter(t => t.id !== action.payload)
        });
    case CLEAR_CART:
        return Object.assign({}, state, {
           cartProducts: [] 
        });
  }
  return state;
}

您可能希望用新数量修改cartProducts。 通过cartproducts进行一个简单的循环就可以了

案例添加到购物车: 返回对象。赋值{},状态{ cartProducts:state.cartProducts.mapitem,索引=>item.id===action.payload.id ?item.quantity++:item.quantity=1
}

首先,当您使用扩展运算符时,它只会为第一级创建新的引用。然而,第二层是指向相同的引用。 例如

在这种情况下,还必须复制第二层。使用扩展运算符,例如

let secondCollection = collection.map(item => {
  let newItem = {
    ...item
  }

  newItem.someData: 2
  return newItem
})

console.log(collection) //[{someData: 1}]
console.log(secondCollection) //[{someData: 2}]
这可能会让人沮丧,有很多方法可以减少困难。规范化是一个好方法。以下是redux州的参考:

如果您喜欢使用第三方库,lodash中有cloneDeep方法,可以为您复制深层次:

对于您的更新购物车:

它可以简化很多。绝对不需要在数组中获取重复项,也不需要在其中循环

让我们试着简化它:

//assuming the carProducts state as
[
  {
    id: 1,
    quantity: 2,
  },
  {
    id: 2,
    quantity: 2,
  }
]

let newState = carProducts.map(item => {
  let newItem = {...item} //or _.cloneDeep(item)

  newItem.quantity = item.quantity + 1 //or add up the payload

  return newItem

})
您还应该在不同的减速器中分离产品、carProducts等状态,以实现简单性和更多控制


如果您有什么不清楚的地方,请随时发表评论:

Safal您可能会得到许多答案,但任何人都可以给出的最好建议是,无需复制阵列,然后对其进行编辑。这是您成功所需的唯一信息。所有可能的数组转换只能使用array.prototype.reduce不可变地执行所有可能的对象转换只能使用object.assign不可变地执行所有可能的对象转换也请提供状态的前后信息,我可以告诉您转换无法在不知道的情况下通读more@ShanonJackson更新了代码。
let secondCollection = collection.map(item => {
  let newItem = {
    ...item
  }

  newItem.someData: 2
  return newItem
})

console.log(collection) //[{someData: 1}]
console.log(secondCollection) //[{someData: 2}]
//assuming the carProducts state as
[
  {
    id: 1,
    quantity: 2,
  },
  {
    id: 2,
    quantity: 2,
  }
]

let newState = carProducts.map(item => {
  let newItem = {...item} //or _.cloneDeep(item)

  newItem.quantity = item.quantity + 1 //or add up the payload

  return newItem

})