React问答应用:为每个答案设唯一ID并更新answerIsHeld状态
React 问答应用问题及代码
这是一个简单的React.js问答应用
App.jsx
import React, { useState, useEffect} from 'react' import './App.css' import QuestionList from './components/QuestionList' import { nanoid } from 'nanoid' export default function App() { const [quizComplete, setQuizComplete] = useState(false) const [questionsBunch, setQuestionsBunch] = useState([]) const [answersDetails, setAnswersDetails] = useState([]) const shuffle = (array) => { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array; }; const getQuestionsData = async () => { const res = await fetch('https://opentdb.com/api.php?amount=5&type=multiple') const questionsData = await res.json() setQuestionsBunch(questionsData.results.map((questionItem, index) => { let options = [ decodeString(questionItem.correct_answer), ...questionItem.incorrect_answers.map(a => decodeString(a)) ] shuffle(options) return { questionId: nanoid(), question: decodeString(questionItem.question), correctAnswer: questionItem.correct_answer, answers: { options: [...options], answerId: nanoid() } } })) } const newAnswersDetails = () => { setAnswersDetails(questionsBunch.map((questionBunch) => { return { question: questionBunch.question, answerIsHeld: false, answerValidity: false, options: questionBunch.answers } })) } const decodeString = str => { const textArea = document.createElement('textarea') textArea.innerHTML = str return textArea.value } useEffect(() => { getQuestionsData() }, []) useEffect(() => { newAnswersDetails() }, [questionsBunch]) console.log(answersDetails) const holdAnswer = id => { console.log(id) } const checkAnswers = () => { if(answersDetails.every(answerDetails => answerDetails.answerIsHeld)){ setQuizComplete(true) } !quizComplete && getQuestionsData() } return ( <> <QuestionList questionsBunch={questionsBunch} checkAnswers={checkAnswers} quizComplete={quizComplete} answersDetails={answersDetails} holdAnswer={holdAnswer} /> </> ) }
QuestionList.jsx
import React from 'react' import Question from './Question' export default function QuestionList(props) { return( <div className="question-bank"> {props.questionsBunch.map(questionBunch => { return ( <> <Question questionBunch={questionBunch} key={questionBunch.id} answersDetails={props.answersDetails} holdAnswer={props.holdAnswer} /> </> ) })} <div className={props.quizComplete && "quiz-check-complete"}> <p className='answer-count'>{props.quizComplete ? `You scored 5/5 correct answers` : ' '}</p> <button className={props.quizComplete ? "quiz-btn-complete" : "quiz-btn"} onClick={props.checkAnswers}>{props.quizComplete ? "Play Again" : "Check Answers"}</button> </div> </div> ) }
Question.jsx
import React from 'react' export default function Question(props) { const answerStyles = () => { let bg props.answersDetails.map(answerDetails => { answerDetails.answerIsHeld ? bg = 'lightgray' : bg = 'transparent' }) return { backgroundColor: bg } } return( <div className='question' key={props.questionBunch.id}> <p className="question-header">{props.questionBunch.question}</p> <div className="answers" key={props.questionBunch.id}> {props.questionBunch.answers.options.map(option => { return( <div className="answer" style={answerStyles()} onClick={() => { console.log(option.answerId) }} > <p className="answer-text">{option}</p> </div> ) })} </div> <hr></hr> </div> ) }
问题及需求
现有代码中answerId未与每个独立答案正确关联,同一道题的四个答案共用同一个ID,需要实现以下功能:
- 点击每个答案时,控制台打印其唯一ID
- 支持点击选中答案,同一题目可切换选中的答案
- 完成所有题目答案选择后,可校验答案正确性
核心目标是点击答案时匹配其唯一ID,并更新对应的answerIsHeld状态。
内容的提问来源于stack exchange,提问作者Hussein
相关产品推荐
相关产品推荐

