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

React中map渲染列表时onClick作用于所有项的解决方法

问题根源

你当前的实现把激活状态存在单个布尔值active中,所有遍历生成的列表项都共用这一个状态做样式判断,点击任意项触发状态更新后,所有项读取到的状态值同步变化,自然会一起切换样式,无法实现单一项的独立状态标记。另外原代码还存在JSX标签未闭合的语法问题。

修复方案

根据业务场景分两种实现方式:

  • 单选模式:同一时间仅允许一个分类处于激活状态,适合分类互斥的筛选场景
  • 多选模式:可同时选中多个分类,支持多条件叠加筛选场景

单选模式实现

将状态从布尔值改为存储当前激活项的唯一ID,渲染时逐项判断自身ID是否和激活ID匹配,匹配才加载激活样式:

const Product = ({categories}) => {
    // 存储当前激活的分类ID,初始值可设为null(默认无选中)或指定分类ID
    const [activeId, setActiveId] = useState(null)

    const handleCategoryClick = (categoryId) => {
        // 点击同一项时可设为null取消选中,不需要取消选中直接setActiveId(categoryId)即可
        setActiveId(activeId === categoryId ? null : categoryId)
    }

    return (
        <div className="flex flex-col">
            <div className="pt-8 mx-4">
                <h5 className="mx-4 text-2xl font-semibold">Kategoriler</h5>
                <ul className="flex">
                    {categories?.map((category)=>(
                        <li 
                            onClick={() => handleCategoryClick(category.id)}
                            className={
                                activeId === category.id 
                                ? "p-2 bg-yellow-200 shadow-lg m-2 transition duration-300 cursor-pointer" 
                                : "p-2 bg-white shadow-lg m-2 transition duration-300 cursor-pointer"
                            } 
                            key={category.id}
                        >
                            {category.title}
                        </li>
                    ))}
                </ul> 
            </div>
        </div>
    )
}

export default Product;

多选模式实现

将状态改为存储所有激活项的ID数组,点击时判断当前项ID是否在数组中:已存在则移除(取消激活),不存在则加入(设为激活):

const Product = ({categories}) => {
    // 存储所有处于激活状态的分类ID
    const [activeIdList, setActiveIdList] = useState([])

    const handleCategoryClick = (categoryId) => {
        setActiveIdList(prev => {
            return prev.includes(categoryId)
                ? prev.filter(id => id !== categoryId)
                : [...prev, categoryId]
        })
    }

    return (
        <div className="flex flex-col">
            <div className="pt-8 mx-4">
                <h5 className="mx-4 text-2xl font-semibold">Kategoriler</h5>
                <ul className="flex">
                    {categories?.map((category)=>(
                        <li 
                            onClick={() => handleCategoryClick(category.id)}
                            className={
                                activeIdList.includes(category.id)
                                ? "p-2 bg-yellow-200 shadow-lg m-2 transition duration-300 cursor-pointer" 
                                : "p-2 bg-white shadow-lg m-2 transition duration-300 cursor-pointer"
                            } 
                            key={category.id}
                        >
                            {category.title}
                        </li>
                    ))}
                </ul> 
            </div>
        </div>
    )
}

export default Product;

内容的提问来源于stack exchange,提问作者Ekrem Günden

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:57:32