【问题标题】:React Redux update item quantity (more than just one increment)React Redux 更新项目数量(不止一个增量)
【发布时间】:2021-01-28 05:37:53
【问题描述】:

我有一个网站,用户可以在该网站上增加产品的数量,然后再将其添加到购物车。现在,如果用户决定返回产品并通过增加产品数量再添加 3 个,然后添加到购物车 - 我如何更新购物篮中现有产品的数量?

目前,我会根据选择的内容获得不同数量的产品副本。

这是我的减速器的代码:

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  items: [],
};

const basket = createSlice({
  name: "basket",
  initialState,
  reducers: {
    addToBasket: (state, { payload }) => {
        // No idea what to do with this..
      state.items.filter((pizza) => pizza.name === payload.name);

      // This pushes the item fine, but I get multiple of the same item in the cart instead of just updating its quantity
      state.items.push(payload);



      //   state.items.map((pizza) =>
      //     pizza.name === payload.name
      //       ? {
      //           ...pizza,
      //           quantity: pizza.quantity + payload.quantity,
      //         }
      //       : pizza
      //   );


    },
  },
});

export const { addToBasket } = basket.actions;
export const basketItems = (state) => state.basket.items;

export default basket.reducer;

payload是具体的产品,它会是一个对象:

{
 name: "product name",
 image: "url.jpeg",
 price: "14.99"
}

我一生都无法弄清楚在这里做什么才能不改变状态。没有任何效果,我觉得我已经尝试了所有可能的方法,但显然我错过了一些东西。

非常感谢任何帮助!!!

谢谢

【问题讨论】:

    标签: javascript reactjs ecmascript-6 react-redux redux-toolkit


    【解决方案1】:

    您实际上拥有所需的所有代码,只需要正确应用它即可。首先检查该项目是否已经在items 数组中。如果它已经存在,则复制现有状态并更新匹配元素。如果它包含,则将新项目附加到数组的末尾。

    const basket = createSlice({
      name: "basket",
      initialState,
      reducers: {
        addToBasket: (state, { payload }) => {
          const item = state.items.find((pizza) => pizza.name === payload.name);
    
          if (item) {
            state = state.items.map((pizza) =>
              pizza.name === payload.name
                ? {
                    ...pizza,
                    quantity: pizza.quantity + payload.quantity
                  }
                : pizza
            );
          } else {
            state.items.push(payload);
          }
        },
      },
    });
    

    使用 Redux-Toolkit,您可以改变状态对象,因此您可以稍微简化一下。与其映射一个新数组并将其设置回状态,不如改变找到的对象。

    const basket = createSlice({
      name: "basket",
      initialState,
      reducers: {
        addToBasket: (state, { payload }) => {
          const item = state.items.find((pizza) => pizza.name === payload.name);
    
          if (item) {
            item.quantity += payload.quantity;
          } else {
            state.items.push(payload);
          }
        },
      },
    });
    

    【讨论】:

    • 天哪……你真是个该死的英雄,谢谢!我以前也写过这个,用 find 等检查它是否存在,我唯一没有做的就是将项目设置为状态 = 地图返回!该死的,还有 8 个小时我再也回不来了,松了一口气,谢谢!!
    • @Joe 是的,我仍然习惯 redux-toolkit 如何允许您编写改变状态的 reducer 函数。通常你会返回一个 new 状态对象,但是使用 RTK 你可以改变状态。或者,我认为您可以找到索引并直接按索引对元素进行变异。干杯,祝你好运。
    • 这直接与createSlice 发生变异,这对我来说也很奇怪。鉴于此,我们不能在找到像item.quantity = item.quantity + payload.quantity 这样的匹配项后直接改变项目,而不是映射项目吗?
    • @buzatto 好点。经过进一步考虑,我认为我完全同意你的看法。我用修订/简化版本更新了我的答案。谢谢。
    • 啊,是的,他们在后面使用了 immer。不完全确定它是如何工作的,虽然还没有研究过,但这对我来说也很奇怪。我也尝试过直接变异,这是我的第一个实现,但是对我不起作用,更多的状态变异错误。
    猜你喜欢
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 2022-11-07
    • 1970-01-01
    • 2019-09-08
    • 2020-01-16
    相关资源
    最近更新 更多