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

React/NextJS中onClick触发所有映射项,如何仅精准触发点击的单个项?

问题根因

你当前仅声明了一个全局的布尔类型状态isFlipped,所有通过map渲染的卡片元素都共用这同一个状态判断是否要翻转,所以只要状态变更,所有卡片都会同步触发动画效果。

解决方案

将状态修改为存储当前被点击卡片的唯一标识,仅在当前卡片的标识和状态中存储的标识匹配时触发翻转动画,推荐优先使用业务数据中的唯一ID作为标识,实现代码如下:

// 状态改为存储被翻转卡片的唯一ID,初始值为null代表无卡片被翻转
const [flippedId, setFlippedId] = useState(null);

const flip = (productId) => {
  // 重复点击同一张已翻转的卡片则重置为未翻转状态,否则切换为当前点击的卡片
  setFlippedId(flippedId === productId ? null : productId);
};

return(
data.map((product) => (
  <div 
    onClick={()=> flip(product.id)}
    // 仅当前卡片ID匹配时触发翻转动画
    animate={flippedId === product.id && { rotateY: 180 }}
    key={product.id} // React列表渲染必填的key属性,避免渲染异常
>
    <p>{product.name}</p>
    <p>{product.info}</p>
  </div>
 ));
)

临时替代方案(无唯一ID时)

如果你的product数据暂时没有唯一ID字段,可临时使用map遍历的索引作为标识,不推荐长期使用,列表顺序变更时可能导致状态错乱:

const [flippedIndex, setFlippedIndex] = useState(null);

const flip = (index) => {
  setFlippedIndex(flippedIndex === index ? null : index);
};

return(
data.map((product, index) => (
  <div 
    onClick={()=> flip(index)}
    animate={flippedIndex === index && { rotateY: 180 }}
    key={index}
>
    <p>{product.name}</p>
    <p>{product.info}</p>
  </div>
 ));
)

多卡片同时翻转方案

如果需要支持多张卡片同时保持翻转状态,可将状态改为Set类型存储所有已翻转的卡片ID:

const [flippedIds, setFlippedIds] = useState(new Set());

const flip = (productId) => {
  const newFlippedIds = new Set(flippedIds);
  newFlippedIds.has(productId) ? newFlippedIds.delete(productId) : newFlippedIds.add(productId);
  setFlippedIds(newFlippedIds);
};

return(
data.map((product) => (
  <div 
    onClick={()=> flip(product.id)}
    animate={flippedIds.has(product.id) && { rotateY: 180 }}
    key={product.id}
>
    <p>{product.name}</p>
    <p>{product.info}</p>
  </div>
 ));
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:06:04