Kallol Medhi
Kallol Medhi

Reputation: 589

How to Delete individual items from list in react

I have built a simple ToDo App. Rending the tasks from the form input is working fine, but I am unable to delete the tasks when clicked on Delete button.

export class TodoList extends Component {
  constructor(props) {
    super(props)

    this.state = {
        task:'',
        items:[]
    }
  }
  onChangeHandler=(e)=>{
    this.setState({
        [e.target.name]: e.target.value
    })
  }
  addItem=(e)=>{
    e.preventDefault()
    if (this.state.task!==""){
    this.setState({
        items:[...this.state.items,this.state.task],
        task:''
    })
  }
  }
  removeItem=(index)=>{
    const remainingItems = this.state.items.filter(j => {
      return j !== index
    })
    this.setState({
      items: remainingItems
    })
  };

  render() {
    return (
      <div>
        <form>
            <input type='text' name="task"onChange={this.onChangeHandler} value={this.state.task} placeholder='Enter Task'/>
            <button type='submit' onClick={this.addItem}>Add Task</button>
        </form>
        <Lists items={this.state.items}
                delete={this.removeItem}/>
      </div>
    )
  }
}





export class Lists extends Component {

  removeItems=(index)=>{
    this.props.delete(index)
  }

  render() {
    return (
      <div>
        {this.props.items.map((item,index)=>
            <li className="Lists" key={index}>{item}
            <button type='button' onClick={this.removeItems(index)}>Remove</button>
            </li>)}
      </div>
    )
  }
}

Upvotes: 0

Views: 90

Answers (3)

ivica.moke
ivica.moke

Reputation: 1064

I prefer to pass item that i would like to remove, index can be decieving becouse it changes. Find index by unique key, i use item.id as unique key.

 removeItem = item => {
    const items = this.state.items;
    // if using lodash i use findIndex
    const index = _.findIndex(items, i => i.id === item.id)
    // if plain js
    const index = items.findIndex(i => i.id === item.id)
    items.splice(index, 1);
    this.setState({
      items
    });
  };

Upvotes: 0

Thanveer Shah
Thanveer Shah

Reputation: 3333

You can delete the current item using splice method.

 removeItem = index=> {
    let newArray = this.state.items;
    newArray.splice(index, 1);
    this.setState({
      items: newArray
    });
  };

It would be better to use onClick for removing item like this :

<button type='button' onClick={()=>this.removeItems(index)}>Remove</button>

Hope this helps.

Upvotes: 0

Sebastijan Dumančić
Sebastijan Dumančić

Reputation: 1182

Do you even happen to have any items to delete here or the list comes up empty? Delete function itself looks fine but you have couple of problems here.

  1. Don't use index as a key. In case you're reordering or deleting (which you are doing) an array of items, you can run into a lot of issues. Here's a good article: https://medium.com/@vraa/why-using-an-index-as-key-in-react-is-probably-a-bad-idea-7543de68b17c Probably the error is with this since you're deleting key which, since it's an iterator, is reassigned to another element when array repopulates itself. Change iterator to some other unique identifier for each element.

  2. You're calling removeItems method as soon as it's set. If you have invoked methods (with ()) inside return of render, it will be executed immediately on each refresh. That's why I'm asking do you have anything to delete at all since, if delete function is okay written, this would probably delete all items as soon as they are added.

  3. Best method would be to use dataset. To each element you can add dataset like this:

data-item-id={some-id} and you can fetch it inside your method from the fired event like this const clickedId = event.currentTarget.dataset.someId. Note that dataset in the element must be written like-this, and it's rewritten automatically when fetching it into camelCase (likeThis). Then you can use this index to target the element you want inside the array and delete it.

Note that the iterator issue still applies, and you need a different unique identifier.

Let me know if you need further explanation.

Upvotes: 1

Related Questions