0

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!

2 Answers 2

1

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

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

    return {
      …item,
      completed: true,
    };
});
Sign up to request clarification or add additional context in comments.

2 Comments

Hey, that works, thanks a million. Only thing missing from your code was prevState.list.map(item => ... but you mentioned it in your response so was easy to figure out what the issue was. Thanks a million!
@tjbuton. Yep thx. I changed my answer
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.