You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单设备多账户电商购物车Redux实现:state.carts[ID]未定义问题

问题与修复方案

我开发了一个电商网站,想要实现单台电脑上多账户切换时显示对应账户的购物车商品,写了如下Redux代码:

const initialState = {
  carts: {},
};
const cartSlice = createSlice({
  name: "profile",
  initialState,
  reducers: {
    addToCart: (state, action) => {
     
      if (state.carts[action.payload.id]) {
        const itemExists = state.carts[action.payload.id].find(
          (item) => item.id === action.payload.id
        );
        if (itemExists) {
          itemExists.quantity++;
        } else {
          state.carts[action.payload.id].push({
            ...action.payload.item,
            quantity: 1,
          });
        }
        toast(`${action.payload.title} added`);
      } else {
        return {
          ...state,
          carts: {
            ...state.carts,
            [action.payload.id]: [
              ...state.carts[action.payload.id],
              { ...action.payload.item, quantity: 1 },
            ],
          },
        };
      }
    },
    incrementQuantity: (state, action) => {
      const item = state.cart.find((item) => item.id === action.payload);
      item.quantity++;
    },
    decrementQuantity: (state, action) => {
      const item = state.cart.find((item) => item.id === action.payload);
      if (item.quantity === 1) {
        const index = state.cart.findIndex(
          (item) => item.id === action.payload
        );
        state.cart.splice(index, 1);
      } else {
        item.quantity--;
      }
    },
    removeFromCart: (state, action) => {
      const index = state.cart.findIndex((item) => item.id === action.payload);
      state.cart.splice(index, 1);
    },
  },
}); 

组件中调用addToCart的代码:

onClick={() =>
  dispatch(
    addToCart({
      item,
      id: data.user.user.id,
    })
  )
}

现在遇到错误:state.carts[action.payload.id]未定义,期望的最终状态结构是:

{
  carts:{
    id1:[shopping carts items],
    id2:[shopping carts items],
    ...
  }
}

错误原因与修复

1. addToCart分支的展开错误

在else分支中,...state.carts[action.payload.id]会尝试展开一个undefined(因为此时该用户id对应的购物车还不存在),直接导致报错。同时商品存在性判断混淆了用户id和商品id,应该用action.payload.item.id去匹配购物车中的商品。

2. 其他reducer的状态引用错误

incrementQuantity、decrementQuantity、removeFromCart中都错误引用了state.cart(单数),但实际状态结构是state.carts(复数),且没有指定操作的用户id,无法定位到对应账户的购物车。

修正后的完整代码

const initialState = {
  carts: {},
};
const cartSlice = createSlice({
  name: "profile",
  initialState,
  reducers: {
    addToCart: (state, action) => {
      const { id: userId, item } = action.payload;
      // 先获取当前用户的购物车,不存在则初始化为空数组
      const userCart = state.carts[userId] || [];
      
      // 用商品id判断是否已存在
      const itemExists = userCart.find(cartItem => cartItem.id === item.id);
      if (itemExists) {
        itemExists.quantity++;
      } else {
        userCart.push({ ...item, quantity: 1 });
      }
      
      // 直接更新state(Immer支持这种修改方式)
      state.carts[userId] = userCart;
      toast(`${item.title} added`);
    },
    incrementQuantity: (state, action) => {
      const { userId, itemId } = action.payload;
      const userCart = state.carts[userId];
      if (!userCart) return;
      
      const targetItem = userCart.find(item => item.id === itemId);
      if (targetItem) targetItem.quantity++;
    },
    decrementQuantity: (state, action) => {
      const { userId, itemId } = action.payload;
      const userCart = state.carts[userId];
      if (!userCart) return;
      
      const targetItem = userCart.find(item => item.id === itemId);
      if (!targetItem) return;
      
      if (targetItem.quantity === 1) {
        const index = userCart.findIndex(item => item.id === itemId);
        userCart.splice(index, 1);
      } else {
        targetItem.quantity--;
      }
    },
    removeFromCart: (state, action) => {
      const { userId, itemId } = action.payload;
      const userCart = state.carts[userId];
      if (!userCart) return;
      
      const index = userCart.findIndex(item => item.id === itemId);
      if (index !== -1) userCart.splice(index, 1);
    },
  },
}); 

组件调用更新

其他购物车操作(如增减数量)需要同时传入用户id和商品id,示例:

// 增加商品数量
onClick={() =>
  dispatch(
    incrementQuantity({
      userId: data.user.user.id,
      itemId: item.id,
    })
  )
}

内容的提问来源于stack exchange,提问作者Negar Nasiri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 11:57:46