Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS: Updating array inside object state doesn't trigger re-render

I have a react hooks function that has a state object apiDATA. In this state I store an object of structure:

{
name : "MainData", description: "MainData description", id: 6, items: [
{key: "key-1", name : "Frontend-Test", description: "Only used for front end testing", values: ["awd","asd","xad","asdf", "awdr"]},
{key: "key-2", name : "name-2", description: "qleqle", values: ["bbb","aaa","sss","ccc"]},
...
]
}

My front end displays the main data form the object as the headers and then I map each item in items. For each of these items I need to display the valuesand make them editable. I attached a picture below.

enter image description here

Now as you can see I have a plus button that I use to add new values. I'm using a modal for that and when I call the function to update state it does it fine and re-renders properly. Now for each of the words in the valuesI have that chip with the delete button on their side. And the delete function for that button is as follows:

const deleteItemFromConfig = (word, item) => {
    const index = apiDATA.items.findIndex((x) => x.key === item.key);

    let newValues = item.value.filter((keyWord) => keyWord !== word);

    item.value = [...newValues];

    api.updateConfig(item).then((res) => {
      if (res.result.status === 200) {
        let apiDataItems = [...apiDATA.items];
        apiDataItems.splice(index, 1);
        apiDataItems.splice(index, 0, item);
        apiDATA.items = [...apiDataItems];
        setApiDATA(apiDATA);
      }
    });
  };

Unfortunately this function does not re-render when I update state. And it only re-renders when I update some other state. I know the code is a bit crappy but I tried a few things to make it re-render and I can't get around it. I know it has something to do with React not seeing this as a proper update so it doesn't re-render but I have no idea why.

like image 517
George Ponta Avatar asked Jan 23 '26 01:01

George Ponta


1 Answers

It is not updating because you are changing the array items inside apiDATA, and React only re-render if the pointer to apiDATA changes. React does not compare all items inside the apiDATA.

You have to create a new apiDATA to make React updates.

Try this:

      if (res.result.status === 200) {
        let apiDataItems = [...apiDATA.items];
        apiDataItems.splice(index, 1);
        apiDataItems.splice(index, 0, item);
        setApiDATA(prevState => {
            return {
                ...prevState,
                items: apiDataItems
            }
       });
      }
like image 196
rMonteiro Avatar answered Jan 25 '26 15:01

rMonteiro



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!