Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS: replacing object from array with new value replaces whole array

I have array selectedItems and when I try to update existing object:

i.e. [{lable: "one", uniqueId: 1}, {lable: "two", uniqueId: 1}] 

to:

i.e. [{lable: "one", uniqueId: 1}, {lable: "two", uniqueId: 3}]

It replaces the whole array with:

 [ { lable: "two", uniqueId: 3 }]

how can I avoid that?

handleChange = (label, uniqueId) => {
  const { selectedItems } = this.state
  const findExistingItem = selectedItems.find((item) => {
    return item.uniqueId === uniqueId;
  })

  if(findExistingItem) {
    selectedItems.splice(findExistingItem);
    this.setState(state => ({
      selectedItems: [...state.selectedItems, {
        label, uniqueId
      }]
    }))
  } else {
    this.setState(state => ({
      selectedItems: [...state.selectedItems, {
        label, uniqueId
      }]
    }))
  }
}
like image 748
Hman Avatar asked Nov 26 '22 13:11

Hman


1 Answers

Another approach would be to use the Array#filter and Array#concat functions in tandem, where;

  • items that don't match on uniqueId are filtered. This substitutes the find() logic of your current solution followed by,
  • the concat() method being called to append the new "replacement item" to the end of the filtered array

In code that could be achieved like this:

handleChange = (label, uniqueId) => {
  const {
    selectedItems
  } = this.state

  this.setState({
    selectedItems : selectedItems
      /* Filter any existing item matching on uniqueId */
      .filter(item => (item.uniqueId !== uniqueId))
      /* Append replacement { label, uniqueId } to state array */
      .concat([ { label, uniqueId } ])
  });
}
like image 119
Dacre Denny Avatar answered Nov 29 '22 03:11

Dacre Denny