React题库随机抽题及MCQ组件单选框属性设置咨询
Solution for Your React Quiz App
Hey there! Let's tackle your quiz app requirements with clear, actionable code and explanations.
1. Randomly Select Non-Repeating Questions & Shuffle Options
First, we need a function to pull a specified number of unique questions from your quizQuestions array, plus shuffle the options for each selected question without altering the original data. Here's how to do it:
import quizQuestions from './path-to-your-quiz-file'; // Fisher-Yates shuffle algorithm for fair, unbiased randomization const shuffleArray = (array) => { const shuffled = [...array]; for (let i = shuffled.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; } return shuffled; }; // Get random unique questions and shuffle their options export const getRandomQuestions = (numQuestions = 100) => { // Shuffle the full question bank first to ensure random selection const shuffledQuestions = shuffleArray(quizQuestions); // Take the first N questions (no duplicates since we're using the shuffled list) const selectedQuestions = shuffledQuestions.slice(0, numQuestions); // For each selected question, shuffle its options (create a copy to avoid modifying original data) return selectedQuestions.map(question => ({ ...question, options: shuffleArray(question.options) })); };
How this works:
- The
shuffleArrayfunction uses the Fisher-Yates algorithm, which avoids the bias common in naive shuffling methods. getRandomQuestionsfirst shuffles the entire question bank, then picks the firstnumQuestionsentries to guarantee no repeats.- We create copies of each question and shuffle its options, so the original
quizQuestionsarray stays untouched.
2. Fixing the MCQ Component's id and name Attributes
The core rules for radio button attributes here are:
- Same
namefor all radio buttons in one question: Enforces single selection per question. - Unique
idfor each radio button: Lets labels correctly link to their buttons (no DOM conflicts). - Unique
nameacross different questions: Prevents radio buttons from separate questions interfering with each other.
Here's the updated MCQ component:
function MCQ({ question, options, questionIndex }) { return( <div className="mcq-question"> <div className="question-text">{question}</div> <div className="options-container"> {options.map((option, optionIndex) => { const radioId = `question-${questionIndex}-option-${optionIndex}`; const radioName = `question-${questionIndex}-answer`; return ( <div key={radioId} className="option"> <input type="radio" name={radioName} id={radioId} value={option} /> <label htmlFor={radioId}>{option}</label> </div> ); })} </div> </div> ) }
Explanation of attributes:
name={radioName}: Usesquestion-${questionIndex}-answeras the name. This ensures all radio buttons for the same question share the same name (so only one can be selected), while different questions have unique names to avoid cross-interference.id={radioId}: Usesquestion-${questionIndex}-option-${optionIndex}to create a unique ID for every radio button, eliminating DOM duplicate ID issues.htmlFor={radioId}: Matches the radio button's ID, so clicking the label selects the corresponding radio button (improves accessibility and user experience).- We added a
keyprop to each option div (usingradioId) to satisfy React's list rendering requirements.
Using the MCQ Component
When rendering your quiz, implement it like this (after fetching the random questions):
import { getRandomQuestions } from './quiz-utils'; function QuizApp() { const [questions, setQuestions] = React.useState([]); React.useEffect(() => { // Get 100 random questions (adjust the number as needed) const randomQuestions = getRandomQuestions(100); setQuestions(randomQuestions); }, []); return ( <div className="quiz-container"> {questions.map((question, index) => ( <MCQ key={`question-${index}`} question={question.question} options={question.options} questionIndex={index} /> ))} </div> ); }
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

