Nick Sethi
Nick Sethi

Reputation: 23

Unable to update state on a nested object in React

I'm having trouble understanding state changes in React.

Let's say I have a Test Component that contains Questions and each Question has Answers which the user selects. As written:

class Test extends Component {
  state = {
    activeQuestion: 0,
    questions: {
      selectedAnswer: ''
    }
  }

In the app, only one question is rendered at a time. I want to store each user answer in the Test state. For the selection process, my callback is:

handleOptionSelect = (option) => {
  this.setState({
    ...this.state, 
      questions: {
        selectedAnswer: option.value
      }
    })
  } 

When I am on a particular question, selecting an option updates the state correctly. However, whenever I choose a different question (setting activeQuestion to a different number) the selectedAnswer value persists. How can I ensure the state changes stays in the parent object?

Edit (to provide more context): I assume I could initialize all the question objects in the initial state like below, but that seems time consuming and inefficient. Thanks in advance, y'all

class Test extends Component {
  state = {
    activeQuestion: 0
    questions: {
      {id: 1, selectedAnswer: 'B'},
      {id: 2, selectedAnswer: 'C'},
      {etc},
      {etc}
    }
  }   

Upvotes: 2

Views: 304

Answers (1)

Yury Tarabanko
Yury Tarabanko

Reputation: 45121

Though I'm not 100% sure I understand your requirements correctly, you could do it this way.

Init state.questions with empty object

class Test extends Component {
  state = {
    activeQuestion: 0,
    questions: {
    }
  }

Then whenever you need to update active question selected answer you do

handleOptionSelect = (option) => {
  // it is better to pass a callback if your next state
  // depends on previous state due to async nature of setState

  this.setState(state => ({
    ...state,
    questions: {
      ...state.questions, // keep answers for "non active" questions
      [state.activeQuestion]: option.value // update only active question
    }
  }))
}

Upvotes: 2

Related Questions