我正在尝试创建一个 Quiz
组件,每次呈现一个 Question
并在用户选择其中一个选项时更改它。
然而,每次它呈现下一个问题时,它已经设置了上一个问题的 chosenOption
变量。发生这种情况是因为在我更改问题之前,我使用该 chosenOption
设置了当前问题的新状态,而且奇怪的是(对我而言)这在呈现下一个问题组件时已经设置了。
对我来说,setChosenOption
只会为当前问题设置,当测验呈现下一个问题时,它的 chosenOption
最初将为空。我可能在函数式组件的渲染方式中遗漏了一些东西......那么为什么会发生这种情况?
提前致谢!
const Quiz = () => {
const [currentQuestion, setCurrentQuestion] = React.useState(0)
const [answers, updateAnswers] = React.useState({})
const numberOfQuestions = questions.length
const onChoosenOptionCallbackHandler = ({ hasChosenCorrectOption, chosenOption}) => {
updateAnswers(prevAnswers => ({...prevAnswers, [currentQuestion]: hasChosenCorrectOption }))
setCurrentQuestion(currentQuestion + 1)
}
return (
<QuizBackground>
<QuizContainer>
<Question
question={questions[currentQuestion]}
index={currentQuestion}
numberOfQuestions={numberOfQuestions}
onChoosenOptionCallback={onChoosenOptionCallbackHandler}
/>
</QuizContainer>
</QuizBackground>
)
}
此处,除了第一个问题之外,'Chosen Option: '
日志始终显示上一个呈现的问题中的 chosenOption
,并且不为空。
const Question = ({ question, index, numberOfQuestions, onChoosenOptionCallback }) => {
const [chosenOption, setChosenOption] = React.useState(null)
console.log('Chosen Option: ', chosenOption)
const hasChosenCorrectOption = chosenOption !== null ? (chosenOption == answer) : false
const selectOption = (optionIndex) => {
setChosenOption(optionIndex)
console.log('SELECTED: ', optionIndex, hasChosenCorrectOption, chosenOption)
onChoosenOptionCallback({ hasChosenCorrectOption, optionIndex })
}
return (
{/* I removed other parts not relevant. The RadioOption goes inside a map() from the question alternatives */}
<RadioOption
questionName={questionName}
option={option}
chosen={chosenOption === index}
onSelect={() => selectOption(index)}
key={index}
/>
)
}
答案 0 :(得分:1)
您的问题是由于未将 key
分配给使用 Question
函数呈现的 map
组件。
省略 proper keys(即渲染数组中每个元素的唯一属性)会导致各种奇怪的行为,例如您所描述的。
这样做的原因是 React 使用这些索引进行优化,通过仅重新渲染 props 更改的组件。没有密钥,整个过程就无法正常工作。