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

如何将答题应用跳转改为点击Next按钮切换题目并显示对错提示

答题应用修改方案:点击按钮切换题目并显示答题提示

核心问题分析

  • 原代码中checkAnswer函数直接触发题目切换逻辑,导致选中答案后立刻跳题
  • 单选按钮缺少统一name属性,无法形成单选组,出现多选问题

修改步骤

1. 新增必要状态

添加两个状态跟踪用户选择状态和结果,同时初始化分数与题目计数器为0(避免null引发的错误):

const [points, setPoints] = useState(0);
const [counter, setCounter] = useState(0);
const [selectedIsCorrect, setSelectedIsCorrect] = useState(null); // 记录选中答案是否正确
const [hasSelected, setHasSelected] = useState(false); // 标记是否已选择答案

2. 重构checkAnswer函数

移除跳题逻辑,仅处理答案判断与状态更新,使用函数式更新确保状态准确性:

function checkAnswer(e) {
  const isCorrect = e.target.dataset.correct === "true";
  setSelectedIsCorrect(isCorrect);
  setHasSelected(true);
  
  // 函数式更新分数,避免闭包问题
  if (isCorrect) {
    setPoints(prev => prev + 1);
  }
}

3. 修复单选按钮的单选功能

给所有单选按钮添加相同name属性,形成单选组:

// 在Answer组件的input标签中新增name属性
<input 
  type="radio" 
  className="answer" 
  name="quiz-answer"
  data-correct={props.correct} 
  onChange={props.checkAnswer}
/>

4. 添加答题对错提示

在Quiz组件中新增提示区域,根据选中结果显示对应反馈:

function Quiz(props) {
  return (
    <div className="quiz">
      <div className="question" role="h2">{props.question}</div>
      <ul className="answers">{props.children}</ul>
      {/* 新增答题提示 */}
      {props.hasSelected && (
        <div className={`feedback ${props.selectedIsCorrect ? 'correct' : 'wrong'}`}>
          {props.selectedIsCorrect ? '回答正确!' : '回答错误,再想想?'}
        </div>
      )}
    </div>
  );
}

调用Quiz时传入状态参数:

<Quiz 
  question={question[counter].question}
  hasSelected={hasSelected}
  selectedIsCorrect={selectedIsCorrect}
>

5. 实现Next按钮的切换逻辑

给按钮添加点击事件,处理题目切换与状态重置,最后一题时结束答题;同时添加禁用状态,未选择答案时不可点击:

function handleNextQuestion() {
  if (counter < question.length - 1) {
    setCounter(prev => prev + 1);
  } else {
    setEnd(true);
    setStart(false);
    setCounter(0);
  }
  // 重置选择状态,准备下一题
  setHasSelected(false);
  setSelectedIsCorrect(null);
}

按钮代码:

<button 
  className="next-question" 
  onClick={handleNextQuestion}
  disabled={!hasSelected}
>
  Next question
</button>

修改后的完整代码

import { useState } from 'react';

// 假设Starter和ScoreMessage组件已定义
function Starter({ start }) {
  return <button onClick={start}>Start Quiz</button>;
}
function ScoreMessage({ score }) {
  return <div>你的得分:{score}</div>;
}

function App() {
  const [points, setPoints] = useState(0);
  const [counter, setCounter] = useState(0);
  const [question, setQuestions] = useState([
    // 示例题目数据,可替换为实际数据源
    {
      question: "1+1等于几?",
      answers: [
        { value: "2", correct: true },
        { value: "3", correct: false },
        { value: "4", correct: false }
      ]
    },
    {
      question: "React是哪个公司开发的?",
      answers: [
        { value: "Google", correct: false },
        { value: "Facebook", correct: true },
        { value: "Microsoft", correct: false }
      ]
    }
  ]);
  const [is_started, setStart] = useState(false);
  const [is_end, setEnd] = useState(false);
  const [selectedIsCorrect, setSelectedIsCorrect] = useState(null);
  const [hasSelected, setHasSelected] = useState(false);

  function Answer(props) {
    return (
      <li aria-labelledby='answers-list'>
        <label>
          <input 
            type="radio" 
            className="answer" 
            name="quiz-answer"
            data-correct={props.correct} 
            onChange={props.checkAnswer}
          />
          {props.answer}
        </label>
      </li>
    );
  }
  
  function Quiz(props) {
    return (
      <div className="quiz">
        <div className="question" role="h2">{props.question}</div>
        <ul className="answers">{props.children}</ul>
        {props.hasSelected && (
          <div className={`feedback ${props.selectedIsCorrect ? 'correct' : 'wrong'}`}>
            {props.selectedIsCorrect ? '回答正确!' : '回答错误,再想想?'}
          </div>
        )}
      </div>
    );
  }

  function checkAnswer(e) {
    const isCorrect = e.target.dataset.correct === "true";
    setSelectedIsCorrect(isCorrect);
    setHasSelected(true);
    
    if (isCorrect) {
      setPoints(prev => prev + 1);
    }
  }

  function handleNextQuestion() {
    if (counter < question.length - 1) {
      setCounter(prev => prev + 1);
    } else {
      setEnd(true);
      setStart(false);
      setCounter(0);
    }
    setHasSelected(false);
    setSelectedIsCorrect(null);
  }

  return (
    <div className="Quiz">
      {!is_started ? (
        <div className="start-intro-wrapper">
          <h1 className="name">Quiz App</h1>
          <Starter start={() => setStart(true)} />
        </div>
      ) : (
        <div className="quick-wrapper">
          <Quiz 
            question={question[counter].question}
            hasSelected={hasSelected}
            selectedIsCorrect={selectedIsCorrect}
          >
            {question[counter].answers.map((answer, index) => {
              return (
                <Answer
                  key={index}
                  answer={answer.value}
                  checkAnswer={checkAnswer}
                  correct={answer.correct ? "true" : "false"}
                />
              );
            })}
          </Quiz>
          <button 
            className="next-question" 
            onClick={handleNextQuestion}
            disabled={!hasSelected}
          >
            Next question
          </button>
        </div>
      )}
      {is_end && <div className="results-container"><ScoreMessage score={points} /></div>}
    </div>
  );
}

export default App;

可选样式优化

添加CSS样式让反馈更直观:

.feedback {
  margin-top: 1rem;
  padding: 0.5rem;
  border-radius: 4px;
}
.feedback.correct {
  background-color: #d4edda;
  color: #155724;
}
.feedback.wrong {
  background-color: #f8d7da;
  color: #721c24;
}
.next-question:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:54:16