Clay_F
Clay_F

Reputation: 589

React filter method without mutating state

My current state has this:

state = { items : [{id: 1, text: 'test words'}, {id: 2, text: 'another test'}]

Here's my function to remove objects from the array, trying to avoid mutating state.

handleRemove(passedInId) {

  const myItems = this.state.items

  const newArray = myItems.filter(item => item.id !== passedInId)

  this.setState(prevState => ({
    items: prevState.items = newArray
  }))

  console.log('handle remove runned', passedInId, myItems, newArray)

}

It works perfectly but would like to know if it's not anti-pattern before moving on with my life

Many THANKS!!

Upvotes: 5

Views: 10922

Answers (2)

Vincent D'amour
Vincent D'amour

Reputation: 3903

This is an anti-pattern. React handle state change and your object will not be mutated. This is what setState is for. I'm guessing that you don't want to update your state to avoid re-rendering your component. You can create a class variable and update it like you want without triggering a re-render. Something like this:

class MyComponent extends React.Component {
  constructor(props) {
    this.state = {};
    this.items = [{id: 1, text: 'test words'}, {id: 2, text: 'another test'}];
  }

  handleRemove(passedInId) {
    this.items = this.items.filter(item => item.id !== passedInId)
  }
}

Upvotes: 0

TomW
TomW

Reputation: 4002

Your function is almost right, and you have the right idea. You don't need to use the version of setState that takes a mutator function in your case, instead just do:

handleRemove(passedInId) {

  const myItems = this.state.items

  const newArray = myItems.filter(item => item.id !== passedInId)

  this.setState({
    items: newArray
  })

  console.log('handle remove runned', passedInId, myItems, newArray)

}

To be honest, this is simple enough that a one liner will do:

handleRemove(passedInId) {
  this.setState({items: this.state.items.filter(item => item.id !== passedInId)})
}

Upvotes: 11

Related Questions