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

在React的.map()函数中如何实现单个元素的class类切换?

问题原因

你所有列表项共用了同一个布尔类型的全局状态,状态变更后所有绑定了该状态的元素都会同步变更类名,所以会出现点击一个所有都变的问题。

修复方案

将状态从布尔值改为存储当前激活项的用户ID,切换时只匹配对应ID的项即可实现单个元素类名切换,修复后代码如下:

const ItemList: React.FC<ListItemUserProps> = (props) => {
  const { items } = props;
  // 状态改为存储当前激活项的userId,初始为null代表无激活项
  const [activeUserId, setActiveUserId] = useState<number | string | null>(null);

  function toggleUserOpt(userId: number | string) {
    // 点击相同项则关闭,否则切换为当前点击项
    setActiveUserId(prev => prev === userId ? null : userId);
  }

  return (
    <>
      {items.map((t) => (
        <React.Fragment key={t.userId}>
          <div
            className={`item ${activeUserId === t.userId ? 'show' : 'hide'}`}
            role="button"
            tabIndex={0}
            onClick={() => toggleUserOpt(t.userId)}
            onKeyDown={(e) => {
              // 仅回车和空格触发切换,符合无障碍规范
              if (['Enter', ' '].includes(e.key)) {
                toggleUserOpt(t.userId)
              }
            }}
          >
            {t.userNav.firstName}
          </div>
        </React.Fragment>
      ))}
    </>
  );
};

export default ItemList;

拓展:支持多项同时切换

如果业务需要支持多个项同时展示类,将状态改为存储ID集合即可:

// 初始为空集合,代表无选中项
const [activeUserIds, setActiveUserIds] = useState<Set<number | string>>(new Set());

function toggleUserOpt(userId: number | string) {
  setActiveUserIds(prev => {
    const newSet = new Set(prev);
    newSet.has(userId) ? newSet.delete(userId) : newSet.add(userId);
    return newSet;
  })
}

// 类名判断逻辑调整为判断集合中是否存在当前项ID
className={`item ${activeUserIds.has(t.userId) ? 'show' : 'hide'}`}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:15:03