ivan
ivan

Reputation: 13

SetState is not changing the state value

console.log for item.completion is triggered twice. It displays the new inverted value and switch back to its original value. So, every time toggleTask function is called the item.completion is not changed. What causes this?

toggleTask(id) {
    this.setState(prevState => {
      const newTodos = prevState.todos.map(item => {
        if (item.id === id) {
          item.completion = !item.completion
          console.log(item.completion)
        }
        return item
      })
      return { todos: newTodos }
    })
  }

Upvotes: 1

Views: 67

Answers (1)

ezio4df
ezio4df

Reputation: 4105

The problem is here,

this.setState(prevState => {
  const newTodos = prevState.todos.map(item => {
     if (item.id === id) {
        item.completion = !item.completion // !! HERE !!
        console.log(item.completion)
      }
      return item
   })
   return { todos: newTodos }
})

AS, Object are passed by reference not by value, so when your modifying it the state is getting directly modified and React sees no diff from your return and the state, thus no render takes place.

try something that doesn't mod the object directly, like this,

this.setState(prevState => {
  const newTodos = prevState.todos.map(_item => {
     const item = Object.create(_item);  // NEW
     if (item.id === id) {
        item.completion = !item.completion
        console.log(item.completion)
      }
      return item
   })
   return { todos: newTodos }
})

inspired from JavaScript: How to pass object by value?

Upvotes: 2

Related Questions