Home > Software engineering >  Shorter way to update state of array of object?
Shorter way to update state of array of object?

Time:11-26

Here my React state:

  const [questionList, setQuestionList] = useState([
    {
      _type: "radio",
      answer: "",
      point: "",
      question: "",
      options: ["A", "B"],
    },
  ]);

When the array has many objects, to update an object I code like this and it works fine now:

 <textarea
          rows="2"
          value={questionList[number].question}
          onChange={(e) => {
            let a = questionList[number];
            a.question = e.target.value;
            setQuestionList([
              ...questionList.slice(0, number),
              a,
              ...questionList.slice(number   1),
            ]);
          }}
        ></textarea>

Is there a way to make the variable a declaration inside the setState, I mean these 2 rows:

let a = questionList[number];
a.question = e.target.value;

Edit: Sorry I forgot. number value is the position of the object in the array.

CodePudding user response:

You can copy the questions first, mutate the array and set it as the new state without slicing.

<textarea
  rows="2"
  value={questionList[number].question}
  onChange={(e) => {
    const copy = [...questionList];
    copy[number].question = e.target.value;
    setQuestionList(copy);
  }}
/>

CodePudding user response:

I don't know whether the below code will work or not but give it a try.

const [questionList, setQuestionList] = useState([
    {
      _type: "radio",
      answer: "",
      point: "",
      question: "",
      options: ["A", "B"],
    },
  ]);
When the array has many objects, to update an object I code like this and it works fine now:

 <textarea
          rows="2"
          value={questionList[number].question}
          onChange={(e) => {
            setQuestionList([
              ...questionList.slice(0, number),
              {...questionList[number], question: e.target.value}
              ...questionList.slice(number   1),
            ]);
          }}
        ></textarea>

CodePudding user response:

Something like this

 setQuestionList(prev => {
         prev[number].question = e.target.value;
         return [...prev];
 });

CodePudding user response:

I recommend to you see useReducer hook that created for the management value of state which is object type.

useReducer

  • Related