You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 14:25:24