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

React中加入购物车触发无限循环的修复及商品传值方法

问题原因
  • 核心触发点是JSX事件绑定语法错误:你写的<button onClick=()=>handlecart(product)>漏了包裹回调的大括号,不符合JSX语法规则,会导致回调在组件渲染阶段被直接执行,而不是点击时才触发。渲染阶段执行setCount、setItem会触发组件重渲染,重渲染又再次执行回调触发状态更新,直接形成「渲染→更新状态→重渲染」的无限循环,表现就是购物车数量无故持续上涨。
  • 状态设计不合理:你单独拆分了count和item两个状态存购物车数据,既不支持多商品加入购物车的场景,setCount(count+1)的写法还存在闭包陷阱,连续触发更新时会拿到旧的count值,导致计数错误。
  • 如果你把商品对象直接作为props传给子组件时,父组件每次渲染都会在map里生成新的箭头函数引用,也会导致子组件不必要的重渲染,放大循环问题。
正确实现方式
  1. 重构购物车状态,直接用数组存储所有选中的商品,不需要单独维护count状态,购物车总数量可以通过数组计算得到。
  2. 修正onClick语法,用大括号包裹事件回调,确保回调只在点击时触发。
  3. 状态更新使用函数式写法,规避闭包导致的旧值问题,同时可以直接实现「重复加购商品自动累加数量」的逻辑。

完整修正后的核心代码:

// 定义购物车状态,初始为空数组
const [cartItems, setCartItems] = useState([])

// 加入购物车逻辑
const handleCart = (product) => {
  setCartItems(prevCart => {
    // 判断当前商品是否已经在购物车中
    const isExist = prevCart.some(item => item._id === product._id)
    if (isExist) {
      // 已存在则对应商品数量+1
      return prevCart.map(item => 
        item._id === product._id 
          ? {...item, count: (item.count || 1) + 1} 
          : item
      )
    }
    // 不存在则新增商品到数组,默认购买数量为1
    return [...prevCart, {...product, count: 1}]
  })
}

// 列表渲染部分,只需要修正onClick的语法
{localitem.map((product) => (
  <div key={product._id} className="group relative">
    <div>
      <img
        src={product.image}
        alt={"image"}
        className="w-full h-full object-center object-cover lg:w-full lg:h-full"
      />
    </div>
    <div className="mt-4 flex justify-between">
      <div>
        <h3 className="text-sm text-gray-700 font-semibold">
          {product.name}
        </h3>
      <h4 className="text-base font-medium text-gray-900">
        Price<p className="inline-block line-through">{product.price}</p> 
         ${product.price}
      </h4>
      </div>

      <div className="px-3">
        <button>buy</button>
        {/* 这里给回调加上大括号包裹 */}
        <button onClick={() => handleCart(product)}>cart</button>
      </div>
    </div>
  </div>
))}

后续需要传递数据到订单页面时,直接传cartItems数组即可,购物车总商品数可以通过cartItems.reduce((sum, item) => sum + item.count, 0)计算,不会出现计数异常问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:06:21