Denys
Denys

Reputation: 273

ReactJS how to delete item from list

I have have code that creates <li> elements. I need to delete elements one by one by clicking. For each element I have Delete button. I understand that I need some function to delete items by id. How to do this function to delete elements in ReactJS? My code:

class TodoApp extends React.Component {
    constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.state = {items: [], text: ''};
    }

    render() {
        return (
            <div>
                <h3>TODO</h3>
                <TodoList items={this.state.items} />
                <form onSubmit={this.handleSubmit}>
                    <input onChange={this.handleChange} value={this.state.text} />
                    <button>{'Add #' + (this.state.items.length + 1)}</button>
                </form>
            </div>
        );
    }

    handleChange(e) {
        this.setState({text: e.target.value});
    }

    handleSubmit(e) {
        e.preventDefault();
        var newItem = {
            text: this.props.w +''+this.props.t,
            id: Date.now()
        };
        this.setState((prevState) => ({
            items: prevState.items.concat(newItem),
            text: ''
        }));
    }

    delete(id){          // How that function knows id of item that need to delete and how to delete item?
        this.setState(this.item.id)
    }
}

class TodoList extends React.Component {
    render() {
        return (
            <ul>
                {this.props.items.map(item => (
                    <li key={item.id}>{item.text}<button onClick={this.delete.bind(this)}>Delete</button></li>
                ))}
            </ul>
        );
    }
}

Upvotes: 21

Views: 78432

Answers (1)

Mayank Shukla
Mayank Shukla

Reputation: 104359

You are managing the data in Parent component and rendering the UI in Child component, so to delete item from child component you need to pass a function along with data, call that function from child and pass any unique identifier of list item, inside parent component delete the item using that unique identifier.

Step1: Pass a function from parent component along with data, like this:

<TodoList items={this.state.items} _handleDelete={this.delete.bind(this)}/>

Step2: Define delete function in parent component like this:

delete(id){
    this.setState(prevState => ({
        data: prevState.data.filter(el => el != id )
    }));
}

Step3: Call that function from child component using this.props._handleDelete():

class TodoList extends React.Component {

    _handleDelete(id){
        this.props._handleDelete(id);
    }

    render() {
        return (
            <ul>
                {this.props.items.map(item => (
                    <li key={item.id}>{item.text}<button onClick={this._handleDelete.bind(this, item.id)}>Delete</button></li>
                ))}
            </ul>
        );
    }
}

Check this working example:

class App extends React.Component{
   constructor(){
      super();
      this.state = {
        data: [1,2,3,4,5]
      }
      this.delete = this.delete.bind(this);
   }
   
   delete(id){
      this.setState(prevState => ({
          data: prevState.data.filter(el => el != id )
      }));
   }
   
   render(){
      return(
          <Child delete={this.delete} data={this.state.data}/>
      );
   }
}

class Child extends React.Component{

   delete(id){
       this.props.delete(id);
   }
   
   render(){
      return(
         <div>
           {
              this.props.data.map(el=>
                  <p onClick={this.delete.bind(this, el)}>{el}</p>
              )
           }
         </div>
      )
   }
}

ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>

Upvotes: 45

Related Questions