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

React点击事件逻辑异常:点击正确单词仍触发错误提示

问题描述
  • 预期功能:
    1. 用户点击正确单词时,进入下一个单词的匹配环节
    2. 用户点击错误单词时,弹出提示框
  • 当前异常:点击正确单词时,错误提示框仍会弹出,推测是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,
    },
]

问题根源与修复方案

核心问题

  1. 类型不匹配导致判断失效:handleBoxClick中把currentMeaning赋值为words[currentWordIndex].currectBedeutungIndex(数字类型的索引),但clickedWord是字符串类型的单词标识,数字和字符串永远无法相等,因此无论点击哪个单词都会触发错误提示。
  2. 游戏结束逻辑位置错误:每次点击都会执行boxesClicked + 1 === totalBoxes判断,会导致提前触发游戏结束。
  3. 释义显示逻辑不严谨:固定取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;

关键修复点说明

  1. 修正匹配逻辑:将目标单词改为当前条目下的德语单词,转小写后与盒子的data-word(统一小写)匹配,确保类型和内容一致。
  2. 调整游戏结束判断:仅在正确点击后判断是否完成所有单词匹配,避免误触发。
  3. 正确显示释义:使用配置的currectBedeutungIndex索引获取对应释义,而非固定取第一个元素。
  4. 统一字符串格式:将第三个盒子的data-word改为gutenmorgen,和目标单词的小写格式保持一致。

内容的提问来源于stack exchange,提问作者ابداع التعلم

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:37:55