React答题组件需求:点击题目选项后仅禁用该题其余选项
React答题组件问题修复
问题说明
现有React答题组件存在以下问题:点击任意选项后,所有题目里的选项都会被禁用。需要实现两个需求:
- 点击某道题的选项时,只禁用这道题的其他选项
- 所有题目都作答完成后,显示结果按钮
原组件代码
setIsStarted(true) setCurrentScore(0) setResultCard(false) setCurrentQuestion(0) } const checkOption = (isCorrect) =>{ setDisability(true) if(isCorrect){ setCurrentScore(currentScore+1); } setCurrentQuestion(currentQuestion+1); if(currentQuestion==questions.length-1){ setShowResult(true); } } function showResultButton(showResult){ if (showResult) { return <button className='show-result' onClick={showResultCard}>Show results</button> } } const showResultCard = () =>{ setShowResult(false) setResultCard(true); setIsStarted(false) } function displayResultCard(resultCard){ if(resultCard){ return <div className='score-card'>You have answerd {currentScore}/5 correctly</div> } } const updateDisability = () =>{ setDisability(false) } function DisplayQuesion(){ const quesList = questions.map((element) => { return( <div className='question-card'> <h2>{element.text}</h2> <ul> {element.options.map((option) => { return <button key={option.id} onClick={() => checkOption(option.isCorrect)} disabled={updateDisability}>{option.text}</button> })} </ul> </div> ) }) return (<div>{quesList}</div>) }
修改后的完整代码
import { useState } from 'react'; function QuizComponent() { const [isStarted, setIsStarted] = useState(false); const [currentScore, setCurrentScore] = useState(0); const [resultCard, setResultCard] = useState(false); const [showResult, setShowResult] = useState(false); // 新增状态:记录每道题选中的选项ID,key为题目索引 const [selectedOptions, setSelectedOptions] = useState({}); // 示例题目结构,可根据实际需求替换 const questions = [ { text: "问题1:React的核心特性是什么?", options: [ { id: 1, text: "双向数据绑定", isCorrect: false }, { id: 2, text: "虚拟DOM", isCorrect: true }, { id: 3, text: "后端渲染", isCorrect: false } ] }, { text: "问题2:useState返回的是哪种类型的值?", options: [ { id: 4, text: "一个值", isCorrect: false }, { id: 5, text: "一个数组", isCorrect: true }, { id: 6, text: "一个对象", isCorrect: false } ] } ]; const startQuiz = () => { setIsStarted(true); setCurrentScore(0); setResultCard(false); setShowResult(false); setSelectedOptions({}); // 清空上一轮的选中记录 } const checkOption = (isCorrect, questionIndex, optionId) =>{ // 记录当前题目的选中选项 setSelectedOptions(prev => ({...prev, [questionIndex]: optionId})); // 函数式更新得分,避免闭包导致的计算错误 if(isCorrect){ setCurrentScore(prev => prev + 1); } // 检查是否所有题目都已作答 if(Object.keys(selectedOptions).length + 1 === questions.length){ setShowResult(true); } } const showResultButton = () =>{ if (showResult) { return <button className='show-result' onClick={showResultCard}>查看结果</button> } } const showResultCard = () =>{ setShowResult(false); setResultCard(true); setIsStarted(false); } const displayResultCard = () =>{ if(resultCard){ return <div className='score-card'>你答对了 {currentScore}/{questions.length} 道题</div>; } } const DisplayQuestion = () =>{ const quesList = questions.map((element, questionIndex) => { const selectedOptionId = selectedOptions[questionIndex]; return( <div className='question-card' key={questionIndex}> <h2>{element.text}</h2> <ul> {element.options.map((option) => { // 禁用逻辑:当前题目已有选中选项,且当前选项不是用户选的那个 const isDisabled = selectedOptionId && selectedOptionId !== option.id; return ( <button key={option.id} onClick={() => checkOption(option.isCorrect, questionIndex, option.id)} disabled={isDisabled} > {option.text} </button> ); })} </ul> </div> ) }) return (<div>{quesList}</div>) } return ( <div className='quiz-container'> {!isStarted && !resultCard && <button onClick={startQuiz}>开始答题</button>} {isStarted && DisplayQuestion()} {showResultButton()} {displayResultCard()} </div> ); } export default QuizComponent;
关键修改说明
- 新增状态追踪选中选项:添加
selectedOptions状态,用对象存储每道题用户选中的选项ID,精准控制单题的禁用范围。 - 调整选项禁用逻辑:每个选项的
disabled属性不再依赖全局开关,而是判断当前题目是否已有选中选项,且当前选项不是用户选择的那个——实现点击某题选项后,仅禁用该题其他选项的需求。 - 修复得分计算的闭包问题:将
setCurrentScore(currentScore+1)改为函数式更新setCurrentScore(prev => prev + 1),避免因闭包导致的得分统计错误。 - 完善结果触发条件:原来用
currentQuestion判断是否完成答题的逻辑不准确,现在改为检查selectedOptions的键数量是否等于题目总数,确保所有题目都作答后才显示结果按钮。 - 优化中文显示:将按钮文字和结果提示改为中文,贴合国内使用场景。
内容的提问来源于stack exchange,提问作者Manjunath Reddy
相关产品推荐
相关产品推荐

