为什么选项组件在点击任何选项后重新呈现自己?



我在React中制作测验应用程序,我遇到了一个问题,其中选项组件在单击每个选项后重新渲染自己。

代码

App.js主要应用

export default function App() {
const [questions, setQuestions] = useState([])
const [score, setScore] = useState(0)
// Fetching questions
useEffect(() => { 
async function fetchQuestions(){
const res = await fetch("https://opentdb.com/api.php?amount=10&category=18&difficulty=medium")
const data = await res.json()
setQuestions(data.results)
}
fetchQuestions()
}, [])
// Checking answer on clicking any option
const checkAnswer = (option, questionIndex) => {
if(option === questions[questionIndex].correct_answer){
setScore(prevScore => prevScore+=5)
console.log("correct")
}
else{
setScore(prevScore => prevScore-=1)
console.log("incorrect")
}
}

// Main Screen
return (
<QuizScreen questions={questions} score={score} checkAnswer={checkAnswer} />
)
}

QuizScreen.js呈现测验屏幕的组件

export default function QuizScreen(props) {
// Setting questions
const question = props.questions.map((ques, index) => {
// storing options
const opt = []
opt.push(ques.correct_answer)
opt.push(ques.incorrect_answers[0])
ques.incorrect_answers[1] && opt.push(ques.incorrect_answers[1]) // if option 3 available
ques.incorrect_answers[2] && opt.push(ques.incorrect_answers[2]) // if option 4 available
// Arranging options in random order
for(let i=0; i<opt.length; i++){
let j = Math.floor(Math.random() * (i+1))
let temp = opt[i]
opt[i] = opt[j]
opt[j] = temp
}
// Setting options
const option = opt.map(opt => <Option key={nanoid()} option={opt} questionIndex={index} checkAnswer={props.checkAnswer} />)
// Rendering Questions
return (
<div className="ques-container" key={nanoid()}>
<p className="ques-title">{ques.question}</p>
{option}
</div>
)
})

// Main Screen
return (
<div>
<p>{props.score}</p>
{question}
</div>
)
}

Option.js呈现选项按钮的组件

export default function Option(props) {
const [selected, setSelected] = useState(false)
const btnStyle = {
backgroundColor: selected ? "#D6DBF5" : "#FFFFFF"
}
return (
<button 
className="ques-option"
onClick={() => {
props.checkAnswer(props.option, props.questionIndex)
setSelected(prevState => !prevState)
}}
style={btnStyle}
>
{props.option}
</button>
)
}

我试图单独制作选项组件,但它不工作

将它包裹在useMemo上

const question = useMemo(() => {
return props.questions.map((ques, index) => {
// storing options
const opt = []
opt.push(ques.correct_answer)
opt.push(ques.incorrect_answers[0])
ques.incorrect_answers[1] && opt.push(ques.incorrect_answers[1]) // if option 3 available
ques.incorrect_answers[2] && opt.push(ques.incorrect_answers[2]) // if option 4 available
// Arranging options in random order
for(let i=0; i<opt.length; i++){
let j = Math.floor(Math.random() * (i+1))
let temp = opt[i]
opt[i] = opt[j]
opt[j] = temp
}
// Setting options
const option = opt.map(opt => <Option key={nanoid()} option={opt} questionIndex={index} checkAnswer={props.checkAnswer} />)
// Rendering Questions
return (
<div className="ques-container" key={nanoid()}>
<p className="ques-title">{ques.question}</p>
{option}
</div>
)
})
}, [props.questions])

最新更新