Home > Software design >  How can the index of an object within an array be preserved when modifying an object property while
How can the index of an object within an array be preserved when modifying an object property while

Time:01-12

I am having a React useState-Variable that stores an Array of Objects which are of this Question type:

type Question = {
id: number,
text: string,
otherProps: string,
...... (and so on)
}

Example of my useState

const [questions, setQuestions] = React.useState<Question[]>([{id: 1, text: "hello?", otherProps: "Lorem Ipsum"}])

The order of these Question objects in the useState-Variable Array matters, so my question is: How should the following function be changed so that the text of the Question is changed but the array index of the modified object is maintained/kept? I am aware that currently I am first deleting the object and then placing a newly created on at the end, but I can't figure out another way right now.

function setQuestionTextById(id:number, text:string) {
    if (!questions) return;
    const question:Question|undefined = questions.find(x => x.id === id);
    if (!question) return;
    const newQuestion: Question = {
        ...question,
        text,
    };
    const filteredQuestions = questions.filter(item => item.id !== id);
    setQuestions([...filteredQuestions, newQuestion]);
}

CodePudding user response:

You should use map on the array with a function that checks if the id is the one you want - if so it modifies it with the new text, otherwise leaves it as is.

This way, your whole function becomes:

function setQuestionTextById(id:number, text:string) {
    const updatedQuestions = questions.map(question => question.id === id ? { ...question, text } : question);
    setQuestions(updatedQuestions);
}

Which I find much more readable than the original, as well as preserving order as you say you need.

One further refinement would be to use the functional update form of setQuestions so it doesn't depend on the previous value of questions, but I'll leave that up to you - it may not matter, depending on how this is being used in your component.

CodePudding user response:

after doing questions.find(x => x.id === id) you are getting the reference to the question you want to update, you can directly modify it and then copy the array


question = questions.find(x => x.id === id);
question.text = text;
setQuestions([...questions]) // this needs to be done to update the reference 

  • Related