React答题应用点击选项背景色异常及选项乱序问题求助
Quiz应用异常排查与修复
异常1:点击某题选项影响所有题目样式
原因
全局状态isClickedIndex被所有题目共享,点击任意题目选项时,所有题目中索引匹配的选项都会触发样式变化,导致全局受影响。
修复步骤
- 将全局单一索引状态改为按题目索引存储的对象:
// 替换原有的const [isClickedIndex, setIsClickedIndex] = useState(-1); const [clickedIndexes, setClickedIndexes] = useState({});
- 更新点击事件处理函数,记录当前题目和选项的索引:
function handleClick(quizIndex, optIndex) { setClickedIndexes(prev => ({ ...prev, [quizIndex]: optIndex })); }
- 在选项点击回调中传入题目索引:
// 修改checkEachAnswer函数,新增quizIndex参数 function checkEachAnswer(quizIndex, option, correctAnswer, optIndex) { handleClick(quizIndex, optIndex); // 原有答案校验逻辑保持不变,后续建议优化userAnswer存储方式(见下文) }
- 修改选项样式判断逻辑,仅对当前题目选中的选项高亮:
// 在quiz.map时增加quizIndex参数,选项className判断改为: className={`option ${clickedIndexes[quizIndex] === index ? "active" : ""}`}
异常2:点击选项时各题选项顺序打乱
原因
每次组件渲染(状态更新触发重渲染)时,都会重新调用createRandomOptions生成随机选项,导致选项顺序每次都被打乱。
修复步骤
- 在获取数据后,预先为每个题目生成随机选项并存储:
// 修改useEffect中的数据处理逻辑 .then(data => { const formattedQuiz = data.results.map(item => { const options = [...item.incorrect_answers, item.correct_answer]; return { ...item, randomOptions: createRandomOptions(options) }; }); setQuiz(formattedQuiz); })
- 渲染时直接使用预先生成的随机选项,不再重复调用随机函数:
const quizElements = quiz && quiz.map((eachQuiz, quizIndex) => { return ( <div className="quiz-wrapper" key={quizIndex}> <p className="question">{eachQuiz.question}</p> <ul> {eachQuiz.randomOptions.map((option, index) => <li key={index} className={`option ${clickedIndexes[quizIndex] === index ? "active" : ""}`} onClick={() => checkEachAnswer(quizIndex, option, eachQuiz.correct_answer, index)} > {option} </li> )} </ul> </div> ) });
额外优化建议
当前userAnswer用数组存储正确选项,若多题正确选项相同会导致统计错误,建议改为按题目索引存储答案:
- 初始化状态:
const [userAnswer, setUserAnswer] = useState({});
- 更新答案存储逻辑:
function checkEachAnswer(quizIndex, option, correctAnswer, optIndex) { handleClick(quizIndex, optIndex); // 不管正确与否,存储当前题目选中的选项 setUserAnswer(prev => ({ ...prev, [quizIndex]: option })); }
- 计算得分:
// 在渲染得分前计算 const score = quiz ? Object.entries(userAnswer).reduce((total, [idx, ans]) => { return quiz[idx].correct_answer === ans ? total + 1 : total; }, 0) : 0; // 渲染得分 {showAnswer && <p>You scored {score} / {quiz.length}</p>}
内容的提问来源于stack exchange,提问作者Hi - P
相关产品推荐
相关产品推荐

