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

使用useState结合array.filter实现购物车商品删除功能遇阻

购物车商品删除功能修复方案

我尝试用array.filter方法实现购物车商品删除功能,查了文档和Stack Overflow的解答还是没解决。以下是我的组件代码(核心删除函数deleteItemFromBasket通过按钮onClick触发):

function CheckoutProduct({id, title, price, description, rating, category, image }) {
    const [basket, addToBasket] = useAppContext();

    const deleteItemFromBasket = (id) => {
        addToBasket(basket.filter((task) => task.id !== id));
    };

    return (
    <div>
        {basket.map((element) => {
            if (element === id) {
                return (
                    <div className='grid grid-cols-5 border-b pb-4'>
                         {/* far left */}
                        <Image src={image} height={200} width={200} objectFit='contain' />

                
                    {/* middle */}
                        <div className="col-span-3 mx-5">
                            <p>{title}</p>
                            <p className='text-xs my-2 line-clamp-3'>{description}</p>

                        <button onClick={deleteItemFromBasket} className='button'>delete</button>

                        <h1>items ID in basket: {basket}</h1>
                            <h1>length of array: {basket.length}</h1>
                        </div>

                    {/* right */} 
                        <div>
                            <p>${price}</p>
                        </div>    
                    </div>  
                )
            }
        })}
    </div>
  )
}

上下文提供者代码:

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

const AppContext = createContext();

export function AppWrapper({ children }) {
  var [basket, addToBasket]= useState([]);

 
  return (
    <AppContext.Provider value={[basket, addToBasket]}>
      {children}
    </AppContext.Provider>
  );
}

export function useAppContext() {
  return useContext(AppContext);
}

问题分析

  • 点击事件未传递正确ID:按钮onClick直接绑定deleteItemFromBasket时,没有传递商品ID,函数内的id参数实际是点击事件对象,而非目标商品ID。
  • 渲染逻辑错误:basket.map中用element === id比较,element是购物车商品对象,id是基础类型值,全等判断永远不成立,导致无法正确渲染对应商品。
  • 状态更新逻辑未触发:因为前两个错误,filter方法根本没有用正确的ID过滤购物车数组。

修复后的组件代码

function CheckoutProduct({ id, title, price, description, rating, category, image }) {
    const [basket, addToBasket] = useAppContext();

    const deleteItemFromBasket = () => {
        // 直接使用组件props中的id,避免传参错误
        addToBasket(basket.filter(item => item.id !== id));
    };

    // 检查当前商品是否在购物车中,不存在则不渲染
    const isItemInBasket = basket.some(item => item.id === id);
    if (!isItemInBasket) return null;

    return (
        <div className='grid grid-cols-5 border-b pb-4'>
            {/* 左侧商品图片 */}
            <Image src={image} height={200} width={200} objectFit='contain' />

            {/* 中间商品信息 */}
            <div className="col-span-3 mx-5">
                <p>{title}</p>
                <p className='text-xs my-2 line-clamp-3'>{description}</p>

                <button onClick={deleteItemFromBasket} className='button'>删除</button>

                <h1>购物车商品ID: {JSON.stringify(basket.map(item => item.id))}</h1>
                <h1>购物车商品数量: {basket.length}</h1>
            </div>

            {/* 右侧商品价格 */} 
            <div>
                <p>${price}</p>
            </div>    
        </div>  
    )
}

关键修复点

  1. 简化删除函数参数:直接使用组件接收的id属性,避免点击事件传参错误。
  2. 修正渲染判断逻辑:用some方法检查商品是否在购物车中,替代原有的错误遍历比较,避免无效渲染。
  3. 优化调试信息:将原有的basket直接展示改为显示商品ID数组,更直观查看购物车内容。

额外优化建议

  • 上下文状态更新函数命名改为setBasket,符合React useState的命名规范,避免“添加”语义混淆:
// AppWrapper组件修改
const [basket, setBasket] = useState([]);

return (
    <AppContext.Provider value={[basket, setBasket]}>
      {children}
    </AppContext.Provider>
);

组件内对应修改:

const [basket, setBasket] = useAppContext();

const deleteItemFromBasket = () => {
    setBasket(basket.filter(item => item.id !== id));
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:35:25