NextJs测验应用:如何跟踪打乱数组中的正确答案索引
解决测验应用选项判断问题的两种方案
方案一:给选项添加正确标识(推荐)
处理选项数组时,不要只存纯文本,改成包含text和isCorrect的对象,这样打乱后每个选项都自带判断依据,无需跟踪索引:
import { useState, useEffect } from 'react'; export default function QuizQuestion({ question }) { const { correctAnswer, wrongAnswers } = question; const [options, setOptions] = useState([]); useEffect(() => { // 构造带正确标识的选项数组 const allOptions = [ { text: correctAnswer, isCorrect: true }, ...wrongAnswers.map(ans => ({ text: ans, isCorrect: false })) ]; // 用无偏序的Fisher-Yates算法洗牌 const shuffled = shuffleArray(allOptions); setOptions(shuffled); }, [correctAnswer, wrongAnswers]); // Fisher-Yates洗牌算法,避免sort方法的概率偏序问题 function shuffleArray(array) { const newArray = [...array]; for (let i = newArray.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [newArray[i], newArray[j]] = [newArray[j], newArray[i]]; } return newArray; } const handleOptionClick = (option) => { if (option.isCorrect) { console.log('回答正确!'); // 这里添加正确后的业务逻辑,比如加分、跳转下一题 } else { console.log('回答错误!'); // 错误后的逻辑,比如显示正确答案、扣分 } }; return ( <div> <h3>{question.text}</h3> <div className="options"> {options.map((option, idx) => ( <button key={idx} onClick={() => handleOptionClick(option)} className="option-btn" > {option.text} </button> ))} </div> </div> ); }
方案二:直接对比选项与原始正确答案
如果不想修改数组结构,也可以在点击时直接把选中的选项文本和原始的correctAnswer对比,无需额外跟踪索引:
import { useState, useEffect } from 'react'; export default function QuizQuestion({ question }) { const { correctAnswer, wrongAnswers } = question; const [options, setOptions] = useState([]); useEffect(() => { // 合并去重后洗牌 const allOptions = [...new Set([correctAnswer, ...wrongAnswers])]; const shuffled = shuffleArray(allOptions); setOptions(shuffled); }, [correctAnswer, wrongAnswers]); function shuffleArray(array) { const newArray = [...array]; for (let i = newArray.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [newArray[i], newArray[j]] = [newArray[j], newArray[i]]; } return newArray; } const handleOptionClick = (selectedOption) => { if (selectedOption === correctAnswer) { console.log('回答正确!'); } else { console.log('回答错误!'); } }; return ( <div> <h3>{question.text}</h3> <div className="options"> {options.map((option, idx) => ( <button key={idx} onClick={() => handleOptionClick(option)} > {option.text} </button> ))} </div> </div> ); }
关键注意点
- 避免用
sort(() => Math.random() - 0.5)洗牌,这种方法会导致元素出现概率不均,推荐使用Fisher-Yates算法保证随机性公平。 - Next.js中确保
useEffect的依赖项完整,避免因依赖缺失导致的状态更新异常。
内容的提问来源于stack exchange,提问作者Mayowa
相关产品推荐
相关产品推荐

