如何将键和值对添加到具有传播功能的对象中

how to add key and value pair into object with spread function

我目前正在尝试弄清楚如何处理具有传播功能的可变产品,例如,如果我有一家销售服装的在线商店(类似于下面截取的屏幕截图)

所以我想在用户为同一产品添加不同尺寸时进行捕捉。

Initial_State = {} //empty 

当用户提交尺码为S的Add to cart后,就会变成

{
    0:{
       "S" : 1
    }
}

其中 0 是产品 ID,“S”是产品尺寸,然后是添加到购物车的数量,当用户提交另一个添加到购物车的请求时(尺寸 M)

{
    0:{
       "S" : 1,
       "M" : 1
    }
}

这是我目前的尝试:

const quantityById = (state = initialState, action) => {
  
  const { productId, varient } = action

  switch (action.type) {
    case ADD_TO_CART:
    case INCREMENT_CART_ITEM_QUANTITY:
      return { ...state,
        [productId]: {
           [varient] : (state[productId][varient] || 0) + 1 // not working as expected
        }
      }
    default:
      return state
  }
}

有没有办法实现我打算用传播功能做的事情?我现在似乎无法弄清楚这一点。欢迎发表评论,因为我愿意讨论。

谢谢!

编辑:

这是我用于此实验的测试数据之一

{
        "id": 0, 
        "title": "White Shirt",
        "category": "men",
        "price": 120.00,
        "varient": ["S", "M"],
        "description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse blandit aliquet arcu.",
        "inventory": 100
    },

id 和 varient 都被正确接收,

现在的问题是如果我运行上面的代码我会得到以下错误

编辑 2 我添加了 Kalhan

建议的更改
const quantityById = (state = initialState.quantityById, action) => {
  
  const { productId, varient } = action

  switch (action.type) {
    case ADD_TO_CART:
    case INCREMENT_CART_ITEM_QUANTITY:
      console.log(state)
      return { ...state,
        [productId]: {
          [varient]: (state?.[productId]?.[varient] ?? 0) + 1
        }
      }
    default:
      return state
  }
}

每当我添加新尺寸而不是作为新的 key/value 对添加时,代码现在将覆盖尺寸和更新计数。

编辑 3

添加了建议的更改,但似乎存在一些语法错误

看起来当你第一次调用这个动作时,你的状态只是一个空对象{}

因此,通过尝试执行此代码,js 将尝试获取 state[productId],这将导致 undefined,然后尝试从 undefined 中获取 [varient],然后提出了这个问题

(state[productId][varient] || 0) + 1

你需要做的是检查productId是否已经处于状态,

// Check productId is already in the state, if yes, then get the varient inside it
// If any of these (productId or varient) are not exists then return 0
// basically if there is no value of state[productId][varient], then return 0, without throwing an error
(state?.[productId]?.[varient] ?? 0) + 1

查看 Nullish operator 的工作原理

查看 Optional chaining 的工作原理


  return { ...state,
    [productId]: {
       ...(state?.[productId] ?? {}),
       // This is because you have to keep old state unchanged, and only change only one record there.
       // Basically if there is already state.[productId], then copy it, and in the blow line override only varient of it
       [varient] : (state?.[productId]?.[varient] ?? 0) + 1
    }
  }