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

React按ID分组State数组生成去重购物车并计算数量总价

购物车去重聚合实现方案

核心逻辑

按商品ID对原始购物车数组做分组聚合,统计同ID商品的出现次数作为购买数量,同步计算单类商品总价,不需要修改原有加入购物车的基础逻辑即可生效。如果你用Context做全局状态管理,可以把聚合后的结果作为派生值对外暴露,避免冗余状态。

基础实现(保留原有加入购物车逻辑)

先写通用的聚合函数,遍历原始cart数组生成符合要求的新结构:

const formatCart = (rawCart) => {
  const cartMap = {};
  rawCart.forEach(item => {
    if (cartMap[item.id]) {
      // 同ID商品已存在,累加数量、更新总价
      cartMap[item.id].quantity += 1;
      cartMap[item.id].totalPrice = cartMap[item.id].price * cartMap[item.id].quantity;
    } else {
      // 首次加入该商品,初始化条目
      cartMap[item.id] = {
        id: item.id,
        name: item.name,
        price: item.value,
        quantity: 1,
        totalPrice: item.value
      };
    }
  });
  return Object.values(cartMap);
};

在Context中配合useMemo缓存聚合结果,cart更新时自动计算新值,业务组件直接拿聚合后的数组做结算即可:

import { createContext, useState, useMemo, useContext } from 'react';

const CartContext = createContext();

export const CartProvider = ({ children }) => {
  const [cart, setCart] = useState([]);
  // 原有加入购物车逻辑可直接保留,建议把id作为参数传入,避免依赖闭包游离变量
  const addToCart = (id) => {
    setCart(arr => [...arr, {
      name: infos[id-2].fullName,
      value: infos[id-2].value,
      id: infos[id-2].id
    }]);
  };

  // 派生去重聚合后的购物车数据
  const formattedCart = useMemo(() => formatCart(cart), [cart]);

  return (
    <CartContext.Provider value={{ cart, formattedCart, addToCart }}>
      {children}
    </CartContext.Provider>
  );
};

// 自定义hook方便组件消费
export const useCart = () => useContext(CartContext);

优化方案(从源头维护去重购物车)

如果不想每次渲染都遍历原始数组做聚合,可以直接修改addToCart逻辑,在加入商品时就做去重判断,直接维护符合业务要求的cart结构,后续做数量修改、商品删除、金额计算时逻辑更简洁:

const addToCartOptimized = (id) => {
  const product = infos[id-2];
  setCart(arr => {
    const existItemIndex = arr.findIndex(item => item.id === product.id);
    if (existItemIndex > -1) {
      // 商品已在购物车,数量+1
      const updatedArr = [...arr];
      const currentItem = updatedArr[existItemIndex];
      updatedArr[existItemIndex] = {
        ...currentItem,
        quantity: currentItem.quantity + 1,
        totalPrice: currentItem.price * (currentItem.quantity + 1)
      };
      return updatedArr;
    }
    // 商品不在购物车,新增条目
    return [...arr, {
      id: product.id,
      name: product.fullName,
      price: product.value,
      quantity: 1,
      totalPrice: product.value
    }];
  });
};

该方案下cart本身就是目标结构,不需要额外做格式转换,更适配后续结算、订单提交等业务场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 21:21:26