React useState pre populated from previous component render

I’m trying to create a Quiz component rendering one Question at time and changing it when the user chooses one of the alternatives.

However, every time it renders the next Question it has already the chosenOption variable set from the previous Question. This happens because before I change the Question, I set the new state of the current Question with that chosenOption and strangely(to me) this is already set when the next Question component is rendered.

For me, the setChosenOption would set only for the current Question and when the Quiz renders the next Question its chosenOption would be null initially. I may be missing something from how functional components render… So why is it happening?

Thanks in advance!

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>
    )
}

Here, apart from the first Question, the 'Chosen Option: ' log always show the chosenOption from the previous Question rendered and not null.


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}
          />
    )
}

115 thoughts on “React useState pre populated from previous component render”

Leave a Comment