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

React中如何在map遍历的单个元素内通过onClick修改状态

解决React卡片点击仅展示当前卡片状态的问题

核心思路是用「激活的产品ID」替代全局布尔值,精准控制单个卡片的显示状态,同时用对象存储每个产品的购买次数,避免重复请求。

步骤1:调整状态定义

把原来的isShown换成记录当前激活产品的ID,再新增一个对象存储各产品的购买次数:

const [activeProductId, setActiveProductId] = useState<number | null>(null);
const [purchasedCounts, setPurchasedCounts] = useState<Record<number, number>>({});

步骤2:修改点击事件处理函数

在点击时获取对应产品的购买次数,更新存储对象,并切换当前激活的产品ID:

const handleClick = async (id: number) => {
  // 如果当前已经显示该产品,点击则隐藏
  if (activeProductId === id) {
    setActiveProductId(null);
    return;
  }
  
  // 如果已经获取过该产品的次数,直接显示,不用重复请求
  if (purchasedCounts[id]) {
    setActiveProductId(id);
    return;
  }

  // 异步获取购买次数(假设getAmountOfTimesPurchased是异步函数)
  const count = await getAmountOfTimesPurchased(id);
  setPurchasedCounts(prev => ({ ...prev, [id]: count }));
  setActiveProductId(id);
};

步骤3:修改卡片渲染逻辑

只有当当前卡片的ID和激活ID匹配时,才显示对应的购买次数:

return (
  <div> 
    {products.map((product: IProduct) => {
      return (
        <Card key={product.id}>
          <Card.Body>
            <Card.Text>
              <Card.Title>{product.name}</Card.Title>
              ${product.price}
              <br />
              {product.amount}
            </Card.Text>
          </Card.Body>
          <Card.Footer>
            <Button onClick={() => handleClick(product.id)}>
              Purchased For:
            </Button>
            {activeProductId === product.id && purchasedCounts[product.id]}
          </Card.Footer>
        </Card>
      );
    })}
  </div>
);

补充说明

  • 如果getAmountOfTimesPurchased是同步函数,去掉async/await即可
  • 加入了缓存逻辑,已经获取过的次数不会重复请求,提升性能
  • 支持点击同一按钮切换显示/隐藏状态,如果不需要这个功能,删掉if (activeProductId === id)的判断即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:02:24