无法将现有产品添加到 redux 中的 reducer 中的购物车中,并反应本​​机

cant add existing product in cart in reducer in redux with react native

我正在开发一个有母店的本机应用程序,我正在使用 redux 处理全局状态,在我的减速器中,我必须处理添加到购物车的问题,如果购物车中不存在产品或如果购物车中存在产品,我的目标只是在不增加产品总数的情况下增加其数量 这是我的行动和减速器

export const ADD_TO_CART = 'ADD_TO_CART';
export const ADD_QUANTITY = 'ADD_QUANTITY';
export const SUB_QUANTITY = 'SUB_QUANTITY';

export const DELETE_ITEM = 'DELETE_ITEM';


export const addToCart = (payload) => {
    type: ADD_TO_CART,
    payload
}

export const addQuantity = (payload) => {
    type: ADD_QUANTITY,
    payload
}

export const subQuantity = (payload) => {
    type: SUB_QUANTITY,
    payload
}

export const deleteItem = (payload) => {
    type: DELETE_ITEM,
    payload
}

我的购物车减速器

import { ADD_TO_CART,DELETE_ITEM,SUB_QUANTITY,ADD_QUANTITY} from '../actions/cartItems';

const initialState = {
    itemsCount : 0,
    cartItems:[],
    cartTotalAmount:0,

}

const cartReducer = (state=initialState, action)=>{
    switch(action.type){
        case ADD_TO_CART:
            let cart = {
                id:action.payload.itemId,
                quantity:action.payload.quantity,
                name:action.payload.itemTitle,
                image:action.payload.itemImg,
                price:action.payload.itemPrice,
                cartAmount:action.payload.quantity * action.payload.itemPrice
            }
            
            if(state.itemsCount === 0){
                state.cartItems.push(cart);//just push the cart
                return {
                    ...state,
                    itemsCount:state.itemsCount+1,
                    cartTotalAmount:state.cartItems.map(item => {
                        state.cartTotalAmount+item.cartAmount
                    })
                }
            }else{
                let exists =false;
                let i =0;
                while(i<state.cartItems.length){
                    if(state.cartItems[i].id === action.payload.itemId){
                        state.cartItems[i].quantity++;
                        exists = true;
                    }
                    return{
                        ...state,
                        itemsCount:state.itemsCount
                    }
                    i++;
                }

                state.cartItems.map((key,item) => {
                    if(item.id === action.payload.itemId){
                        // {...item,quantity:item.quantity+1}
                        state.cartItems[key].quantity++;
                        exists = true
                    }
                    return {
                        ...state,
                        itemsCount:state.itemsCount,
                    }
                })
                if(!exists){
                    let _cart = {
                        id:action.payload.itemId,
                        quantity:action.payload.quantity,
                        name:action.payload.itemTitle,
                        image:action.payload.itemImg,
                        price:action.payload.itemPrice,
                        cartAmount:action.payload.quantity * action.payload.itemPrice
                    }
                    state.cartItems.push(_cart)
                    return {
                        ...state,
                        itemsCount:state.itemsCount+1,
                        cartTotalAmount:state.cartItems.map(item => {
                            state.cartTotalAmount+item.cartAmount
                        })
                    }
                }


            }
        case ADD_QUANTITY:
            return {
                ...state,
                cartItems:state.cartItems.map(
                    item => item.id === action.payload.itemId
                    ? {...item, quantity: item.quantity+1 }
                    : item 
                ),
            }
        case DELETE_ITEM:
            let newCartItems = state.cartItems.filter(
                (item) => {return item.id != action.payload.itemId}
            )
            let count = state.itemsCount-1;
            return {
                ...state,
                itemsCount:count,
                cartItems:newCartItems,
            }
        case SUB_QUANTITY:
            return {
                ...state,
                cartItems:state.cartItems.map(
                    item => item.id === action.payload.itemId 
                    ? {...item, quantity: item.quantity-1 } 
                    : item  
                ),
            }
        
        // case ADD_TO_WISH_LIST:
        //     for(let i=0; i < state.wishListItems.length; i++){
        //         if(state.wishListItems[i].id === action.item.id){
        //             return {
        //                 ...state,
        //                 wishListItems: state.wishListItems.map(item => item.id === action.item.id ?
        //                     { ...item, quantity: item.quantity+1 } :item
        //                 ) ,
        //             }
        //         }
        //         else{
        //             let updatedWishListItems = [...state.wishListItems, action.item];   
        //             let count = state.wishCount + 1;
        //         }
        //     }
        //     return{
        //         ...state,
        //         wishCount : count,
        //         wishListItems :updatedWishListItems
        //     }
        
        // case DELETE_FROM_WISH_LIST:
        //     let newWishListItems = state.wishListItems.filter(
        //         (item)=>{
        //          return item.id!=action.item.id
        //         }
        //      );
            
        //      return {
        //         ...state,
        //         wishListItems : newWishListItems , 
        //     }  
        default:
            return state
    }
        
}  

export default cartReducer;

reducer 中添加到购物车的第一种情况,当 itemsCount === 0 工作时,但是当购物车有多个项目时,reducer 无法正确执行并且卡住需要帮助

问题

  1. 不要在状态中存储 itemsCountcartTotalAmount 值,这些值很容易从状态数据中导出。存储重复或派生数据是反模式。

    const initialState = {
      itemsCount : 0, // <-- easily computed from cart items
      cartItems:[],
      cartTotalAmount:0, // <-- easily computed from cart items
    }
    
  2. 不要通过直接推入 cartItems 数组来改变状态。

    state.cartItems.push(cart); // <-- mutates state reference
    
  3. 您需要先搜索 cartItems 以查看您是否已经添加了购物车商品。

解决方案

case ADD_TO_CART:
  const {
    itemId,
    itemImg,
    itemPrice,
    itemTitle,
    quantity,
  } = action.payload;

  // search if item is already in cart by item id
  const inCart = state.cartItems.some(item => item.id === itemId);

  if (inCart) {
    // already in cart, shallow copy cart items
    return {
      ...state,
      cartItems: state.cartItems.map(item => item.id === itemId ? {
        // found item, shallow copy item and update quantity property
        ...item,
        quantity: item.quantity + 1,
      } : item),
    }
  } else {
    return {
      ...state,
      cartItems: [
        // shallow copy cart items
        ...state.cartItems,
        // add new cart item
        {
          id: itemId,
          quantity: quantity,
          name: itemTitle,
          image: itemImg,
          price: itemPrice,
        }
      ],
    }
  }

  ...

您可以对更新购物车项目的其他操作类型应用类似的更新模式。

计算 UI

中的 itemsCount
const itemsCount = cartItems.reduce((count, { quantity }) => count + quantity, 0)

计算cartTotalAmount

const cartTotalAmount = cartItems.reduce(
  (totalAmount, { price, quantity }) => totalAmount + quantity * price,
  0,
);

这些可以在一次传递中组合成一个计算

const { cartTotalAmount, itemsCount } = cartItems.reduce(
  ({ cartTotalAmount, itemsCount }, { price, quantity }) => ({
    cartTotalAmount: cartTotalAmount + quantity * price,
    itemsCount: itemsCount + quantity,
  }),
  {
    cartTotalAmount: 0,
    itemsCount: 0,
  },
);