Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Function just re render one time

I got a problem with this Function. When I trigger this function it only re render the component the first trigger. After that not any more. I cant find the problem 🙁

    function selectAnswer(id, questId) {
        let newArr = questions
        
        for(let i = 0; i < newArr.length; i++){
                
                if(questId === newArr[i].id){
                    const changedAnswers = newArr[i].answers.map(answer => {   
                    return answer.id === id ? 
                    {...answer, selected: !answer.selected} : 
                    {...answer, selected: false}
                    })
                
                newArr.forEach(element => {
                    if(questId === element.id){
                            element.answers = changedAnswers
                     }
                    })
                }
                     
        }   
            setQuestions(newArr)            
    }

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You’re never actually updating the state. This doesn’t create a copy of the array, it just duplicates a reference to the array:

let newArr = questions

So this isn’t setting state to a new array, but just a reference to the same array:

setQuestions(newArr)

Additionally, instead of creating new state, you are mutating the existing state:

element.answers = changedAnswers

Start by creating a new array, even if it contains the same elements as the original:

let newArr = [...questions];

Then, when you want to modify one of those elements, instead of modifying the existing element you would instead replace it with a new one. So instead of this structure:

newArr.forEach(element => {

});

You could instead replace your new array with a .map() over itself:

newArr = newArr.map(element => {

});

And within that .map() you would return either the unmodified object or the replacement object:

newArr = newArr.map(element => {
  if(questId === element.id) {
    return {...element, answers: changedAnswers};
  } else {
    return element;
  }
});

Overall, the idea here is that you don’t want to loop over an existing array, modify its values, and set that array back to state. That’s not "updating state" in the React sense but instead it’s "mutating state". Instead, create a new array and populate it with the objects you want. Those objects can be a mix of unchanged objects from the existing array and replaced (not modified) objects from the existing array.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading