从之前的组件渲染中预填充的 React useState

时间:2021-01-30 11:35:13

标签: javascript reactjs use-state

我正在尝试创建一个 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}
          />
    )
}

1 个答案:

答案 0 :(得分:1)

您的问题是由于未将 key 分配给使用 Question 函数呈现的 map 组件。

省略 proper keys(即渲染数组中每个元素的唯一属性)会导致各种奇怪的行为,例如您所描述的。

这样做的原因是 React 使用这些索引进行优化,通过仅重新渲染 props 更改的组件。没有密钥,整个过程就无法正常工作。