【问题标题】:Increment value of array of objects redux增加对象数组re​​dux的值
【发布时间】:2020-09-18 10:47:20
【问题描述】:

如果状态数组中已经存在商品,我需要增加购物车中商品的数量。在减速器中,我让它工作,但它需要是不可变的。因此,我的组件没有正确更新。

这是我的减速器的代码:

import { ADD_TO_CART, REMOVE_FROM_CART } from '../actions/types';

const initialState = [];

//Cannot mutate array in reducer 

export default function(state = initialState, action){
    const { type, payload } = action;

    switch(type){
        case ADD_TO_CART:
            const newState = [...state]
            for(var i = 0; i < newState.length; i++){
                if(newState[i].item.uid === payload.item.uid){
                    newState[i].item.qty ++;
                    return [...newState];
                }
            }
            return [...state, payload];
        case REMOVE_FROM_CART:
            for(var j = 0; j < state.length; j++){
                    if(state[j].item.uid === payload.uid){
                        state[j].item.qty = 1;
                    }
            }
            return state.filter(cartItem => cartItem.item.uid !== payload.uid);

        default:
            return state;
    }
}

如果 item 已经在数组中,我需要增加 qty。

【问题讨论】:

    标签: javascript arrays reactjs redux react-redux


    【解决方案1】:

    我看到的问题是newState[i].item.qty++;,尽管您浅层地复制了数组,但数组中的元素仍然代表先前状态的元素,因此增加它会改变对象。

    要解决此问题,您还应该将每个项目复制到一个新对象中,然后更新 new 对象引用。

    以下内容还包括一个小优化,通过检查匹配的项目 ID 因为将数据复制到新数组中,从而迭代数据一次而不是两次。

    let itemExists = false;
    const newState = state.map(item => {
      const newItem = { ...item };
      if (newItem.item.uid === payload.item.uid) {
        itemExists = true;
        newItem.item.qty = item.qty + 1;
      }
      return newItem;
    });
    
    if (!itemExists) newState.push(payload);
    
    return newState;
    

    编辑:替代方法

    const itemIndex = state.findIndex(item => item.item.id === payload.item.id);
    if (itemIndex !== -1) {
      return state.map((item, i) => ({
        ...item,
        item: {
          ...item.item,
          qty: item.item.qty + (itemIndex === i ? 1 : 0),
        }
      }));
    } else {
      return [...state, payload];
    }
    

    【讨论】:

    • 几乎明白了,但不幸的是我运行了 redux immutable state invariant,它给出了一个错误:在调度中检测到状态突变,在路径中:cart.0.item.qty。看看处理动作 {"type":"ADD_TO_CART","payload":{"item":{"name":"hamburger","price":12,"category":" 的 reducer(s)晚餐","数量":2,"uid":"d23ff8-4056-38b6-7e3-41ec8e01871"}}}。
    • @chrus54321 更新答案,试试newItem.qty = item.qty + 1; 无论如何它是一种更常见的模式,不应该改变任何旧的引用。如果这不起作用,那么我有另一个想法。
    • @chrus54321 好的,我刚刚注意到的一件事是您的状态数组元素使用嵌套的item 键,所以我的第一个答案可能错过了这个,也许这就是您的测试发现的突变。我已经更新了它并添加了我正在考虑的替代方法。
    猜你喜欢
    • 1970-01-01
    • 2017-04-25
    • 2022-01-08
    • 2015-06-03
    • 2021-06-21
    • 1970-01-01
    • 2021-06-04
    • 2014-01-12
    • 2018-08-27
    相关资源
    最近更新 更多