React-Bootstrap Modal仅显示删除购物车最后一个映射元素如何解决
问题根因
所有循环渲染的购物车项共用同一个modalShow布尔状态,点击任意删除按钮都会将该状态置为true,导致所有商品对应的模态框同时被触发显示,最后一个渲染的商品模态框会覆盖在最上层,所以你看到的永远是最后一个商品的删除确认,执行的删除操作也对应最后一个商品。
另外你当前用index作为循环项的key属性也不合理,建议替换为商品唯一idprodid,避免后续列表排序、删除时出现渲染异常。
推荐解决方案:全局仅保留一个模态框(性能最优)
不需要给每个购物车项都单独渲染模态框,全局只放一个模态框,点击删除时记录当前要操作的商品信息即可,修改代码如下:
- 调整状态定义
// 替换原来的布尔类型状态 modalShow const [activeDeleteItem, setActiveDeleteItem] = useState(null);
- 调整渲染结构,把模态框移到购物车循环外部
{/* 全局共用一个模态框 */} <VerticalModal mShow={!!activeDeleteItem} hide={() => setActiveDeleteItem(null)} item={() => { removeFromCartHandler(activeDeleteItem.prodid); setActiveDeleteItem(null); }} name={activeDeleteItem?.prodname || ''} /> {/* 购物车列表渲染 */} {cart && cart.cartItems.length > 0 && cart.cartItems.map((item) => ( <Card key={item.prodid} className=" cart-card-magninn cart-card-shadow" > <Row className="p-3"> <Col>{item.img}</Col> <Col>{item.name}</Col> <Col md={2} xs={2}> <button onClick={() => setActiveDeleteItem(item)} > <FontAwesomeIcon icon={faTrashAlt} /> </button> </Col> </Row> ))}
备选方案:每个购物项单独维护模态框显示状态
如果需要保留每个商品对应单独模态框的写法,可以把显示状态改为存储当前要删除的商品id:
// 替换原来的布尔类型状态 modalShow const [showModalProdId, setShowModalProdId] = useState(null);
循环内的按钮和模态框修改为:
<button onClick={() => setShowModalProdId(item.prodid)} > <FontAwesomeIcon icon={faTrashAlt} /> </button> <VerticalModal mShow={showModalProdId === item.prodid} hide={() => setShowModalProdId(null)} item={() => removeFromCartHandler(item.prodid)} name={item.prodname} />
该方案会渲染多个模态框实例,性能略低于第一种方案,更推荐使用全局单模态框的写法。
内容的提问来源于stack exchange,提问作者Harshit Singh
相关产品推荐
相关产品推荐

