如何将答题应用跳转改为点击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
相关产品推荐
相关产品推荐

