Richard Mbabie
Richard Mbabie

Reputation: 23

Removing an item from a todo list in react

I"ve been trying my hands on learning react and just hit a snag. Having issue understanding passing props across child components as relates to the problem being encountered. I'm having problems deleting an item from my todo list and can for the life of me figure out wat's wrong.

import React, { Component } from 'react';
import Form from './components/Form';
import Todo from './components/Todo';

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      userInput: "",
      todoList: [] 
    }
    this.onChange= this.onChange.bind(this);
    this.addItem=this.addItem.bind(this);
    this.handleDelete=this.handleDelete(this);
  }
  //update input state
  onChange=(e)=>{
        this.setState({
      userInput: e.target.value
    })
  }
  //update todo list
  addItem=(e)=>{
    e.preventDefault();
    if(this.state.userInput!==""){
      const userData={
        //create a specific user id for each input
        id: Math.random(),
        value: this.state.userInput

      }
      const list=[...this.state.todoList];
    list.push(userData);
    
    //Reset userInput after inputing data
    this.setState({
      userInput: "",
      todoList: list
    
    })
    }
    

    
  }
  //Deleting an item
  
  handleDelete=(id)=>{
    const list=[...this.state.todoList];
    const updatedList=list.filter(item=>item.id!==id)
    this.setState({
      todoList:updatedList
    })
  }

  
 
  
  
  
  render() {
    
    return(
      <div>
        <h1>
          My Todo List
        </h1>
        <Form value={this.state.userInput} onChange={this.onChange} onSubmit={this.addItem} />
        <Todo list={this.state.todoList} onDelete={this.handleDelete}/>
      </div>
      
    ) 
      
  }
}
 
export default App;

Above is the parent component

import React, { Component } from 'react';

class Form extends Component {
    
    render() { 
        return (
            <div>
                <form >
                    <input type="text" value={this.props.value} onChange={this.props.onChange}/><button className="btn btn-primary" type="submit" onClick={this.props.onSubmit}>add</button>
                </form>
       
            </div>
           
          );
    }
}
 
export default Form;
import React, { Component } from 'react';


class Todo extends Component {
     
    render() { 
        const todos=this.props.list.map((item,index)=><li key={item.id}>{item.value} <i onClick={this.props.onDelete(item.id)} class="fas fa-trash"></i></li>)

        return ( 
            <div>
              <ul>
              {todos}    
            </ul>  
            </div>
         );
    }
}
 
export default Todo;

Upvotes: 1

Views: 1202

Answers (2)

Chris
Chris

Reputation: 59541

You almost got it right. You need to provide a callback to your onClick handler.

The way you have it now you are providing the onClick handler with the result of running that function. In other words onDelete is being called on each render and onClick is given the return value of onDelete (which is undefined).

You want to give it the function itself. Just change it to:

onClick={() => this.props.onDelete(item.id)}

EDIT: You also made a mistake in your binding of this.handleDelete. It should be:

this.handleDelete = this.handleDelete.bind(this);

but you did:

this.handleDelete = this.handleDelete(this);

which is why you got the error.

Upvotes: 1

richardaum
richardaum

Reputation: 6777

Apparently, your Todo component isn't providing the click handler properly:

<i onClick={this.props.onDelete(item.id)} class="fas fa-trash"></i>

should be:

<i onClick={() => this.props.onDelete(item.id)} class="fas fa-trash"></i>

The reason is because onClick expects a function and passing it this way onClick={this.props.onDelete(item.id)} provides the return of the onDelete function.

Upvotes: 1

Related Questions