简体   繁体   中英

How can the index of an object within an array be preserved when modifying an object property while using the spread operator?

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM