3

How do we create specific fields of object in the array?

Here is my state data that I want to partially update.

state.items = [
     {id:0, left: 100, right: 100, classified: true},
     {id:1, left: 200, right: 300, classified: false}, 
]

And this is expected result after setState.

// Edit left, right, classified with given values,
// where the object's id is equal to 1.
state.items = [
     {id:0, left: 100, right: 100, classified: true},
     {id:1, left: 300, right: 200, classified: true}, 
]

Here is code inside of function (Problem)

//console.log(id) <- prints 1. We are modifying the second object in the array with id 1.

// iterate items array
let { items } = this.state;
for (var index in items) { 
  if(items[index].id === id) {
     // copy the whole object matching id is 1.
     var deep = _.cloneDeep(tag); 

     //Assign new values (newLeft: 300, newRight:200, newCalssified: true)
     deep.left = newLeft
     deep.right = newRight
     deep.classified = newClassified

    this.setState({
      // HERE IS THE QUESTION
      taggedClothes // how do we modify the object with id 1??
    })
  }
}

THANKS!!

merry-go-round
  • 4,533
  • 10
  • 54
  • 102

3 Answers3

3

You need to modify the entire items array and then do a setState to update that entire items array.

const items = _.cloneDeep(this.state.items);

// Find index to modify
const index = items.findIndex(i => i.id === id);
items[index].left = newLeft;
items[index].right = newRight;
items[index].classified = newClassified;

this.setState({items});

EDIT: as mentioned below, it is not always a good idea to mutate the state. I have added a _.cloneDeep at the beginning but have a look at this post for more info and other options: React: How do I update state.item[1] on setState? (with JSFiddle)

klugjo
  • 19,422
  • 8
  • 57
  • 75
1

@klugjo's answer is correct but to change reference make a deep clone of current state to change state:

const {items} = _.cloneDeep(this.state);

// Find index to modify
const index = items.findIndex(i => i.id === id);
items[index].left = newLeft;
items[index].right = newRight;
items[index].classified = newClassified;

this.setState({ items });
Rehan Haider
  • 893
  • 11
  • 26
0

As stated in previous answers you have to modify the entire items array. Here is another approach to do the same using reduce in a cleaner way.

this.setState({
  items: this.state.items.reduce(function(acc, item) {
    if (item.id === id) {
      item.left = newLeft;
      item.right = newRight;
      item.classified = newClassified;
    }
    acc.push(item);
    return acc;
  }, [])
});
Vipin Kumar
  • 6,441
  • 1
  • 19
  • 25