0

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]);
}
David
  • 57
  • 1
  • 6

1 Answers1

2

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.

Robin Zigmond
  • 17,805
  • 2
  • 23
  • 34
  • wouldn't it need to be `{...question, text: text}` ? – bcstryker Jan 11 '23 at 22:10
  • 1
    that's the same thing in longhand form. I just prefer typing less, along with most developers. See eg [here](https://stackoverflow.com/questions/34414766/javascript-object-literal-what-exactly-is-a-b-c) for an explanation – Robin Zigmond Jan 11 '23 at 22:17