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

React购物车商品数量增减按钮点击后页面消失问题排查

购物车数量增减按钮点击后页面消失问题修复

问题描述

用Material UI构建表单与表格单元格,编写了一段React购物车代码,该代码可在localhost:3000正常显示内容,但点击数量增减按钮时页面会消失,怀疑是useState函数使用不当。相关代码如下:

原State与处理函数代码

const[products,setProducts]=useState([
    {
        'cartItems':[
            {
                name: 'Cherry',
                quantity: 1,
                image:"https://media.istockphoto.com/photos/cherry-trio-with-stem-and-leaf-picture-id157428769?b=1&k=20&m=157428769&s=170667a&w=0&h=F1PxAjsNGhS0svv0t_kMRYdAE3UGISZD_BY066-SubU=",
                price:200,
            },
            {
                name:'Almonds',
                quantity:1,
                image:"https://media.istockphoto.com/photos/almonds-picture-id153711056?b=1&k=20&m=153711056&s=170667a&w=0&h=8exR9-QE1WweR4ijYM7XdlELsrKBYLQyi7ILRexnHg4=",
                price :100
            },
            {
                name:'Onions',
                quantity:1,
                image:'https://media.istockphoto.com/photos/red-onion-slice-picture-id175448479?b=1&k=20&m=175448479&s=170667a&w=0&h=kcjadYpPSifmgaESFhA7EKVMdLmL-pXPhrwSvJM0o2U=',
                price : 200
            }
        ],
        'totalPrice':500,
        'count':3
    }
]);

const handleDecrement = (prod_name) =>{
    setProducts(products => 
        products[0].cartItems.map((product) =>
         prod_name===product.name ? {...product,quantity:product.quantity-(product.quantity > 1 ? 1 :0)}:product
        )
        
    );
   
}
const handleIncrement = (prod_name) => {
    setProducts(products => 
        products[0].cartItems.map((product) =>
         prod_name===product.name ? {...product,quantity:product.quantity+1}:product
        )
    );
    
}

原表格单元格代码

<TableCell align="left" size="small" width={10}>
    <form>
        <div class="value-button" id="decrease" onClick={()=>handleDecrement(product.name)} value="Decrease Value"><RemoveIcon/></div>
        <input type="number" id='number' value={product.quantity} />
        <div class="value-button" id="increase" onClick={()=>handleIncrement(product.name)} value="Increase Value"><AddIcon/></div>
    </form>
</TableCell>

问题分析

  1. State结构被破坏:setProducts调用直接返回了cartItems数组,原本的products是包含cartItems、totalPrice、count的对象数组,修改后products变成了纯商品项数组,后续渲染时找不到原有结构,导致页面崩溃。
  2. 表单默认提交:点击按钮时触发了表单的默认提交行为,导致页面刷新。

修复代码

修改后的处理函数

const handleDecrement = (prod_name) => {
    setProducts(prevProducts => {
        // 复制原数组中的第一个购物车对象
        const updatedCart = {...prevProducts[0]};
        // 更新对应商品的数量,确保不小于1
        updatedCart.cartItems = updatedCart.cartItems.map(product => 
            prod_name === product.name 
                ? {...product, quantity: Math.max(product.quantity - 1, 1)}
                : product
        );
        // 重新计算总价和商品总数
        updatedCart.totalPrice = updatedCart.cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0);
        updatedCart.count = updatedCart.cartItems.reduce((total, item) => total + item.quantity, 0);
        // 返回保持原结构的数组
        return [updatedCart];
    });
};

const handleIncrement = (prod_name) => {
    setProducts(prevProducts => {
        const updatedCart = {...prevProducts[0]};
        updatedCart.cartItems = updatedCart.cartItems.map(product => 
            prod_name === product.name 
                ? {...product, quantity: product.quantity + 1}
                : product
        );
        // 同步更新总价和总数
        updatedCart.totalPrice = updatedCart.cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0);
        updatedCart.count = updatedCart.cartItems.reduce((total, item) => total + item.quantity, 0);
        return [updatedCart];
    });
};

修改后的表格单元格代码(阻止表单提交)

<TableCell align="left" size="small" width={10}>
    <form onSubmit={(e) => e.preventDefault()}> {/* 阻止表单默认提交行为 */}
        <div className="value-button" id="decrease" onClick={()=>handleDecrement(product.name)} value="Decrease Value"><RemoveIcon/></div>
        <input type="number" id='number' value={product.quantity} readOnly /> {/* 设置只读避免手动输入干扰 */}
        <div className="value-button" id="increase" onClick={()=>handleIncrement(product.name)} value="Increase Value"><AddIcon/></div>
    </form>
</TableCell>

关键说明

  • 始终保持products的原数组结构,只修改内部对象的字段,避免结构突变导致渲染错误。
  • 阻止表单默认提交行为,彻底解决页面刷新问题。
  • 同步更新totalPrice和count,保证购物车数据一致性。
  • 给数量输入框添加readOnly,避免用户手动修改数量引发的额外逻辑问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:48:53