Kotetsu
Kotetsu

Reputation: 13

React, update state with .map() and spread operator in nested array of objects

I'm still a newbie in React and I've been struggling for some time with the topic mentioned above. I've got a state which looks like this:

const [questions, setQuestions] = React.useState([])    
    React.useEffect(()=>{
        fetch('https://the-trivia-api.com/api/questions?limit=5&difficulty=medium').then((response)=>response.json()).then((data)=>{
            let questionsData = data.map((item) => {
                return {
                    id: nanoid(),
                    questionText: item.question,
                    answerOptions: [
                        {id: nanoid(), answerText: item.correctAnswer, isCorrect: true, selected: false,},
                        {id: nanoid(), answerText: item.incorrectAnswers[0], isCorrect: false, selected: false,},
                        {id: nanoid(), answerText: item.incorrectAnswers[1], isCorrect: false, selected: false,},
                        {id: nanoid(), answerText: item.incorrectAnswers[2], isCorrect: false, selected: false,},
                    ].sort(()=>Math.random() -0.5),
                };
            })
            setQuestions(questionsData)
            })
        
    }, [])

It's a state that returns me a quiz question and 4 "randomized" buttons. What I'm trying to do is to update the state to make one of the answerOptions (that is buttons) from selected: false to selected: true. I'm sure it's doable with .map and spread operator but I'm really lost with the syntax

selectAnswer is triggered by an onChange from the radio buttons from the child Component. I have access to both the question id and each of the answerOptions id so accessing those is not a problem. I just can't figure out how to return the state. Below is an example of my failed attempt to do that.

    function selectAnswer(answerId, questionId){
        setQuestions(prevData => prevData.map((item)=>{
            return item.answerOptions.map((answerItem)=>{
                if(answerId === answerItem.id) {
                    return {...item, [answerOptions[answerItem].selected]: !answerOptions[answerItem].selected}
                } else return {...item}
            })
        }))
        }

Thank you for your time in advance

Upvotes: 1

Views: 995

Answers (2)

lvndry
lvndry

Reputation: 438

Not directly related to the initial question but I recommend you read this part of the react documentation on how to fetch data using useEffect

Upvotes: 0

Konrad
Konrad

Reputation: 24661

function selectAnswer(answerId, questionId) {
  setQuestions((prevData) =>
    prevData.map((item) => ({
      ...item,
      answerOptions: item.answerOptions.map((answerItem) => ({
        ...answerItem,
        selected: answerId === answerItem.id,
      })),
    }))
  );
}

Upvotes: 1

Related Questions