0

我正在练习 React,开发一个商店,以添加我使用示例的购物车的功能。

但是在我的实现中,即使我的版本几乎相同,“添加到购物车”按钮也不会区分每个产品,这意味着:

  • 第一次单击影响所有按钮,不仅单击的一个按钮和其他按钮更改为“添加更多”图例
  • 每次后点击只会添加更多用户第一次点击的同类产品,如果点击另一个则忽略。

似乎是由 Reducer Function 中的突变引起的错误:

export const CartReducer = (state, action) => {
switch (action.type) {
    case 'ADD_ITEM':
      if (!state.cartItems.find((item) => item.id === action.payload.id)) {
        //-------HERE
        state.cartItems.push({
          //mutation here?
          ...action.payload,
          quantity: 1,
        });
        //-------
  }

  return {
    ...state,
    ...sumItems(state.cartItems),
    cartItems: [...state.cartItems],
  };

有什么替代方法?如何在没有突变的情况下推送状态中的项目?

完整的 te 文件在这里

在这里您可以检查部署并复制错误,这里是正确的功能演示

4

2 回答 2

0

您正在改变原始的state,这在 redux 中是不好的做法。你可以做的是这样的事情来防止它:

export const CartReducer = (state, action) => {
    switch (action.type) {
        case 'ADD_ITEM':
            if (!state.cartItems.find((item) => item.id === action.payload.id)) {
                // If you have Lint problems with this declaration, you can set a variable before the switch
                const cartItems = [...state.cartItems, action.payload];

                return {
                    ...state,
                    ...sumItems(cartItems),
                    cartItems,
                };
            }

            return state;
    }
}
于 2021-01-03T23:22:34.073 回答
0

state.cartItems.push 在这里是错误的,你正在改变状态(反模式)。

首先你检查你的项目是否存在,就像你在乞讨时所做的那样。如果项目存在,只需返回状态。如果不是,您可以返回,您可以将您的状态返回为

return {
                    ...state,
                    ...sumItems(state.cartItems + 1),
                    cartItems: [...state.cartItems, action.payload],
                };

在详细介绍和复杂的更新操作之前,您应该熟悉数组破坏、对象破坏、浅拷贝、扩展操作、复制数组、切片、拼接、过滤操作等主题。否则你可能会像上面那样执行一些直接突变。如果它们太复杂,你可以使用其他使操作更容易的库,例如 immutable.js 但请记住,使用额外的库会导致小的性能损失。

https://redux.js.org/recipes/using-immutablejs-with-redux

于 2021-01-03T23:23:10.490 回答