React点击事件逻辑异常:点击正确单词仍触发错误提示
问题描述
- 预期功能:
- 用户点击正确单词时,进入下一个单词的匹配环节
- 用户点击错误单词时,弹出提示框
- 当前异常:点击正确单词时,错误提示框仍会弹出,推测是
onClick事件逻辑存在问题
代码示例
组件代码
const ParFour = () => { const [boxPosition, setBoxPosition] = useState({ x: 0, y: 0 }); const containerSize = { width: 400, height: 400 }; const boxSize = { width: 50, height: 50 }; const [gameOver, setGameOver] = useState(false); const [currentWordIndex, setCurrentWordIndex] = useState(0); const [boxesClicked, setBoxesClicked] = useState(0); const totalBoxes = 3; const handleBoxClick = (event) => { if (!gameOver) { const box = event.target; const currentMeaning = words[currentWordIndex].currectBedeutungIndex; const clickedWord = box.getAttribute('data-word'); if (box.style.display !== 'none') { if (clickedWord === currentMeaning) { box.style.display = 'none'; setBoxesClicked((prevBoxesClicked) => prevBoxesClicked + 1); setCurrentWordIndex((prevIndex) => prevIndex + 1); } else { alert('Wrong word!'); } } if (boxesClicked + 1 === totalBoxes) { setGameOver(true); } } }; const currentWord = words[currentWordIndex]; const currentMeaning = currentWord.bedeutung[0]; return ( <div className='part-four-container'> <div> <p className='bedeutung-container' key={0}>{currentMeaning}</p> </div> {!gameOver && ( <div> <div className='hallo' data-word="hallo" style={{ top: `${boxPosition.y}px`, left: `${boxPosition.x}px`, }} onClick={handleBoxClick} > hallo </div> <div className='danke' data-word="danke" style={{ top: `${boxPosition.y * Math.floor(Math.random() * 5)}px`, left: `${boxPosition.x * Math.floor(Math.random() * 5)}px`, }} onClick={handleBoxClick} > danke </div> <div className='gutenMorgen' data-word="gutenMorgen" style={{ top: `${boxPosition.y * Math.floor(Math.random() * 5)}px`, left: `${boxPosition.x * Math.floor(Math.random() * 5)}px`, }} onClick={handleBoxClick} > Guten Morgen</div> </div>)} {gameOver && ( <div > <p className='game-over'>Spiel ist aus</p> <button className='gam-over-button' onClick={handleRefreshClick}>nochmal abspielen</button> </div> )} </div> ); }; export default ParFour;
单词数组
const words = [ { word: 'Hallo', bedeutung: ['مرحبا','اهلا'], currectBedeutungIndex: 0, }, { word: 'Guten Morgen', bedeutung: ['صباح الخير','مرحبا'], currectBedeutungIndex: 0, }, ]
问题根源与修复方案
核心问题
- 类型不匹配导致判断失效:
handleBoxClick中把currentMeaning赋值为words[currentWordIndex].currectBedeutungIndex(数字类型的索引),但clickedWord是字符串类型的单词标识,数字和字符串永远无法相等,因此无论点击哪个单词都会触发错误提示。 - 游戏结束逻辑位置错误:每次点击都会执行
boxesClicked + 1 === totalBoxes判断,会导致提前触发游戏结束。 - 释义显示逻辑不严谨:固定取
bedeutung[0],没有使用配置的currectBedeutungIndex索引。
修复后的完整代码
const ParFour = () => { const [boxPosition, setBoxPosition] = useState({ x: 0, y: 0 }); const containerSize = { width: 400, height: 400 }; const boxSize = { width: 50, height: 50 }; const [gameOver, setGameOver] = useState(false); const [currentWordIndex, setCurrentWordIndex] = useState(0); const [boxesClicked, setBoxesClicked] = useState(0); // 改为动态获取单词总数,避免固定值和实际数组长度不匹配 const totalWords = words.length; const handleBoxClick = (event) => { if (gameOver) return; const box = event.target; // 跳过已隐藏的盒子 if (box.style.display === 'none') return; // 获取当前需要匹配的德语单词(转小写统一格式) const targetGermanWord = words[currentWordIndex].word.toLowerCase(); const clickedWord = box.getAttribute('data-word'); if (clickedWord === targetGermanWord) { box.style.display = 'none'; const newBoxesCount = boxesClicked + 1; setBoxesClicked(newBoxesCount); // 判断是否完成所有单词匹配 if (newBoxesCount === totalWords) { setGameOver(true); } else { setCurrentWordIndex(prev => prev + 1); } } else { alert('Wrong word!'); } }; const currentWord = words[currentWordIndex]; // 使用配置的索引获取正确的释义 const currentMeaning = currentWord.bedeutung[currentWord.currectBedeutungIndex]; return ( <div className='part-four-container'> <div> <p className='bedeutung-container'>{currentMeaning}</p> </div> {!gameOver && ( <div> <div className='hallo' data-word="hallo" style={{ top: `${boxPosition.y}px`, left: `${boxPosition.x}px`, }} onClick={handleBoxClick} > hallo </div> <div className='danke' data-word="danke" style={{ top: `${boxPosition.y * Math.floor(Math.random() * 5)}px`, left: `${boxPosition.x * Math.floor(Math.random() * 5)}px`, }} onClick={handleBoxClick} > danke </div> <div className='gutenMorgen' data-word="gutenmorgen" style={{ top: `${boxPosition.y * Math.floor(Math.random() * 5)}px`, left: `${boxPosition.x * Math.floor(Math.random() * 5)}px`, }} onClick={handleBoxClick} > Guten Morgen</div> </div> )} {gameOver && ( <div > <p className='game-over'>Spiel ist aus</p> <button className='gam-over-button' onClick={() => window.location.reload()}>nochmal abspielen</button> </div> )} </div> ); }; export default ParFour;
关键修复点说明
- 修正匹配逻辑:将目标单词改为当前条目下的德语单词,转小写后与盒子的
data-word(统一小写)匹配,确保类型和内容一致。 - 调整游戏结束判断:仅在正确点击后判断是否完成所有单词匹配,避免误触发。
- 正确显示释义:使用配置的
currectBedeutungIndex索引获取对应释义,而非固定取第一个元素。 - 统一字符串格式:将第三个盒子的
data-word改为gutenmorgen,和目标单词的小写格式保持一致。
内容的提问来源于stack exchange,提问作者ابداع التعلم
相关产品推荐
相关产品推荐

