React中如何获取点击元素?卡片点击存储对应key的问题求助
解决React卡片点击存储ID的问题
问题根源
- 每次只存最后一个卡片ID:你的
CardClick函数里循环遍历了所有CardData,每次循环都调用setClickedCard,React的state更新是批量异步的,最后一次调用会覆盖前面所有操作,而且你根本没获取到当前点击卡片的ID,而是把所有卡片都加了一遍,最后只剩最后一个。 - console.log显示旧值:
useState的更新是异步的,当你执行console.log(clickedCard)时,state还没完成更新,所以打印的是更新前的旧值。
修改后的完整代码
import React, { useState, useEffect } from "react"; import { CardData } from "./Data/CardsData.js"; import style from "../style/Cards.css"; import Score from "./Score.js"; const Cards = () => { const [bestScore, setBestScore] = useState(0); const [scoreRN, setScoreRN] = useState(0); const [clickedCard, setClickedCard] = useState([]); // 处理卡片点击,接收当前卡片ID const CardClick = (cardId) => { // 避免重复添加相同ID if (!clickedCard.includes(cardId)) { // 使用函数式更新,确保拿到最新的state setClickedCard((prevClicked) => [...prevClicked, cardId]); // 更新当前分数 setScoreRN((prev) => prev + 1); // 更新最高分 setBestScore((prev) => Math.max(prev, scoreRN + 1)); } else { // 重复点击时重置分数和已点击列表 setScoreRN(0); setClickedCard([]); } }; // 监听clickedCard变化,打印最新值 useEffect(() => { console.log("已点击的卡片ID:", clickedCard); }, [clickedCard]); return ( <div id="content"> <Score bestScore={bestScore} scoreRN={scoreRN} /> {CardData.map((data) => { return ( <div key={data.id} className="card" onClick={() => CardClick(data.id)}> <img src={data.img} alt={data.name} /> <h2>{data.name}</h2> </div> ); })} </div> ); }; export default Cards;
关键修改点说明
- 传递当前卡片ID:在
map渲染卡片时,把data.id作为参数传给CardClick,确保点击时能拿到当前卡片的唯一标识。 - 函数式更新state:使用
setClickedCard((prevClicked) => [...prevClicked, cardId]),这种方式能获取到最新的state值,避免因为闭包导致的旧state问题。 - 避免重复添加:通过
!clickedCard.includes(cardId)判断当前ID是否已存在,防止数组中出现重复值。 - 正确打印state:用
useEffect监听clickedCard的变化,当state更新后自动执行打印,确保看到的是最新值。 - 分数逻辑补充:添加了分数更新和重复点击重置的逻辑,符合这类卡片交互的常见需求,你可以根据自己的需求调整。
内容的提问来源于stack exchange,提问作者Habizsabi
相关产品推荐
相关产品推荐

