Home > database >  Feedback on Updating State Array of Objects in React
Feedback on Updating State Array of Objects in React

Time:01-31

I'm making a fairly simple React app to get some of the key concepts, however, I'm struggling a bit with updating my state. I got it to a point where it's working but it's not exactly working as intended.

this.state = {
      list: [{
        id: 1,
        title: 'Figure out how to update state',
        completed: false
      },
      {
        id: 2,
        title: 'Drink less coffee',
        completed: false
      }]
    }
completeItemHandler = (id) => {
    this.setState(prevState => {
      const list = prevState.list.filter(item => item.id === id);
      list[0].completed = true;
      return ({...list})
    },() => console.log(this.state))
  }

the console log returns:

{
    "id": 1,
    "title": "Figure out how to update state",
    "completed": true
},
list: [
    {
        "id": 1,
        "title": "Figure out how to update state",
        "completed": true
    },
    {
        "id": 2,
        "title": "Drink less coffee",
        "completed": false
    }
]

so it looks like it's both updates the state and appended that list object to the state as well which is obviously not what I want. Could someone please explain where I went wrong with this please? I'm not sure why it's created a new object in the state while also updating the object in the list array of objects.

Any help would be much appreciated and a solution to this would be appreciated also!

CodePudding user response:

Because you spread array list to Object. I would suggest use prevState.map instead filter -> mutation and spread.

prevState => ({
  …prevState,
  list: prevState.list(item => {
    if (item.id !== id) return item;

    return {
      …item,
      completed: true,
    };
});

CodePudding user response:

Got this to work using:

completeItemHandler = (id) => {
    this.setState( prevState => {
      const listIndex = prevState.list.findIndex(item => item.id === id);
      //prevState.list[listIndex].completed = !prevState.list[listIndex].completed; // doesn't work
      prevState.list[listIndex].completed = true; //works

      return (
          {...prevState}
      )
    },() => console.log(this.state))
  }

However, this resulted in some weird behaviour doing prevState.list[listIndex].completed = !prevState.list[listIndex].completed; where it wouldn't work. The console.log would output the right value but the state would never update with it.

@Kirill Skomarovskiy's answer is a lot easier to read/ understand for me compared to that so I've used that instead

  •  Tags:  
  • Related