George Bleasdale
George Bleasdale

Reputation: 351

Strange behaviour when removing item from state array

I have an array in state which contains various components. When I click the remove button on one of the components, it removes the first item from the array instead. I only seem to have this problem when using components in the array, it works fine with an array of strings.

Parent component:

addItem = (block) => {
  const add = [...this.state.items, block];
  this.setState({items: add})
}

removeItem = (index) => {
  const remove = [...this.state.items];
  remove.splice(index, 1);
  this.setState({items: remove})
}

render(){
  return(
    <div className="Board">
      <div className="BoardContainer">
        {this.state.items.map((item, index) => { return <Item remove= {this.removeItem} key={index} >{item}</Item>})}
      </div>
      <button onClick={() => this.addItem(<BannerImage />)}>Banner Image</button>
      <button onClick={() => this.addItem(<ShortTextCentered />)}>Short Text Centered</button>
    </div>
  )
}

Child component:

export class Item extends React.Component {

  handleRemove = () => {
    this.props.remove(this.props.index)
  }

  render() {
    return (
      <div className="item">
        {this.props.children}
        <button onClick={this.handleRemove} >Remove</button>
      </div>
    )
  }
}

Upvotes: -1

Views: 119

Answers (2)

Ole EH Dufour
Ole EH Dufour

Reputation: 3240

Array.prototype.splice() mutates the array, so it's better not to use splice() with React.

Easiest to use Array.prototype.filter() to create a new array.

Furthermore working with unique id's rather than indexes prevents from unexpected results.

let filteredArray = this.state.item.filter(x=> x!== e.target.value)
this.setState({item: filteredArray});

Upvotes: 0

Tom Mendelson
Tom Mendelson

Reputation: 625

You used inside your component 'this.props.index' but you didn't pass the index to your component.

you should do something like this:

{this.state.items.map((item, index) => { return <Item remove={this.removeItem} key={index} index={index} >{item}</Item>})}

Upvotes: 1

Related Questions