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

Redux Toolkit reducer中if/else未按id+size匹配规则正常工作

购物车Redux逻辑异常问题

需求与问题现象

  • 预期实现逻辑:
    • 购物车已存在同ID同尺码的商品时,对应商品数量加1
    • 添加同ID不同尺码的同款商品时,作为独立条目单独展示
  • 异常表现:代码中已经添加了同时匹配商品ID与size的find查找条件,但实际运行时仅校验商品ID就执行数量递增,未校验size属性。

问题相关原代码如下:

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

const initialState = {
  bagData: [],
};

export const bagDataSlice = createSlice({
  name: "bagDataProducts",
  initialState,
  reducers: {
    sendDataToCardComponent: (state, action) => {
      let { id, size } = action.payload;

      const findItemById = state.bagData.find(
        (item) => item.id === id && item.size === size
      );

      if (findItemById) {
        state.bagData.filter((item, i) => (state.bagData[i].quantity += 1));
      } else {
        state.bagData.push({ ...action.payload, quantity: 1 });
      }
    },
    increaseItemQuantity: (state, { payload }) => {
      state.bagData.filter((item, i) =>
        item.id === payload ? (state.bagData[i].quantity += 1) : item
      );
    },
    decreaseItemQuantity: (state, { payload }) => {
      state.bagData.filter((item, i) =>
        item.id === payload && item.quantity > 1
          ? (state.bagData[i].quantity -= 1)
          : item
      );
    },
    removeItem: (state, { payload }) => {
      state.bagData = state.bagData.filter((item) => item.id !== payload);
    },
  },
});

问题产生原因

  • 匹配成功后的递增逻辑完全写错:你用find确实正确匹配到了同ID同尺码的商品,但进入if (findItemById)分支后,调用filter遍历购物车数组时没有加任何判断条件,遍历到每一个商品都会执行quantity +=1,等于给购物车所有商品数量都加1,根本没有操作你之前找到的目标匹配项。
  • 后续数量增减、删除逻辑本身就没有做尺码校验:increaseItemQuantity、decreaseItemQuantity、removeItem三个方法都只判断了商品ID,完全没有接收size参数做匹配,同ID下所有尺码的商品会被同时修改数量、同时删除,本身就不符合独立条目的设计要求。
  • 方法误用:filter的作用是按条件筛选返回新数组,不适合用来做遍历修改操作,无意义的遍历和返回值会增加额外性能开销,也容易引发逻辑错误。

修复方案

直接操作已经找到的匹配项修改数量,同时所有涉及商品操作的reducer都同时校验ID和size两个字段,修复后代码如下:

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

const initialState = {
  bagData: [],
};

export const bagDataSlice = createSlice({
  name: "bagDataProducts",
  initialState,
  reducers: {
    sendDataToCardComponent: (state, action) => {
      const { id, size } = action.payload;
      // 匹配同ID同尺码商品
      const existItem = state.bagData.find(
        (item) => item.id === id && item.size === size
      );

      if (existItem) {
        // 直接给匹配到的商品数量+1,不需要全量遍历
        existItem.quantity += 1;
      } else {
        state.bagData.push({ ...action.payload, quantity: 1 });
      }
    },
    // 入参需要同时传id和size
    increaseItemQuantity: (state, { payload }) => {
      const { id, size } = payload;
      const targetItem = state.bagData.find(item => item.id === id && item.size === size);
      if (targetItem) targetItem.quantity += 1;
    },
    decreaseItemQuantity: (state, { payload }) => {
      const { id, size } = payload;
      const targetItem = state.bagData.find(item => item.id === id && item.size === size);
      if (targetItem && targetItem.quantity > 1) targetItem.quantity -= 1;
    },
    removeItem: (state, { payload }) => {
      const { id, size } = payload;
      // 删除时同时匹配id和size,只删对应尺码的条目
      state.bagData = state.bagData.filter(item => !(item.id === id && item.size === size));
    },
  },
});

export const { sendDataToCardComponent, increaseItemQuantity, decreaseItemQuantity, removeItem } = bagDataSlice.actions;
export default bagDataSlice.reducer;

注意:调用后面三个增减、删除方法时,dispatch的payload需要同时传入商品的id和size两个参数,才能精准定位到对应尺码的商品条目。


内容的提问来源于stack exchange,提问作者Berke Palamutcu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:45:36