1

I have a simple ToDo application written in React. I cannot figure out how to remove the ToDos.

I have two separate files App.js

    import React, { Component } from 'react';
    import './App.css';
    import ToDo from './components/ToDo.js';

    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          todos: [
            { id: 1, description: 'Walk the cat', isCompleted: true },
            { id: 2, description: 'Throw the dishes away', isCompleted: false },
            { id: 3, description: 'Buy new dishes', isCompleted: false}
          ],
          newTodoDescription: ''
        };
        this.deleteTodo = this.deleteTodo.bind(this);
      }

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

    handleSubmit(e) {
      e.preventDefault();
      if (!this.state.newTodoDescription) { return }
      const newTodo = { description: this.state.newTodoDescription, isCompleted: false };
      this.setState({ todos: [...this.state.todos, newTodo], newTodoDescription: '' });
    }


    toggleComplete(index) {
      const todos = this.state.todos.slice();
      const todo = todos[index];
      todo.isCompleted = todo.isCompleted ? false : true;
      this.setState({ todos: todos });
    }


    deleteTodo(id) {
      this.setState((prevState) => ({
        items: prevState.items.filter(item => item.id !== id),
      }))
    }


      render() {
        return (
          <div className="App">
            <form onSubmit={ (e) => this.handleSubmit(e)}>
              <input type="text"
                value={ this.state.newTodoDescription }
                onChange={ (e) => this.handleChange(e) }
                />
              <input type="submit" />
            </form>
            <ul>
              { this.state.todos.map( (todo, index) =>
                <ToDo key={ index }
                  description={ todo.description }
                  isCompleted={ todo.isCompleted }
                  toggleComplete={ () => this.toggleComplete(index) }
                  onDelete={ this.deleteTodo }
                   />
              )}

            </ul>
          </div>
        );
      }
    }

    export default App;

The second file is ToDo.js

     import React, { Component } from 'react';

      class ToDo extends Component {
        render() {
          return (
            <li>
              <input type="checkbox" checked={ this.props.isCompleted } onChange={ this.props.toggleComplete } />
              <button onClick={() => this.props.deleteTodo(this.props.id)}>Delete</button>
              <span>{ this.props.description }</span>
            </li>
          );
        }
      }

      export default ToDo;

When I click on the button I am presented with an error: TypeError: _this2.props.deleteTodo is not a function

How can I get my current code to work?

1
  • 2
    It should be this.props.onDelete(this.props.id) Commented Feb 3, 2018 at 13:50

2 Answers 2

3

The name of your prop is onDelete, so in your component ToDo.js, you have to call your function like below

<button onClick={() => this.props.onDelete(this.props.id)}>Delete</button>

as answer to your comment

your state is define like

   this.state = {
      todos: [
        { id: 1, description: 'Walk the cat', isCompleted: true },
        { id: 2, description: 'Throw the dishes away', isCompleted: false },
        { id: 3, description: 'Buy new dishes', isCompleted: false}
      ],
      newTodoDescription: ''
    };

So, your function deleteTodo should be like

deleteTodo(id) {
    this.setState((prevState) => ({
        todos: prevState.todos.filter(item => item.id !== id),
    }))
};
Sign up to request clarification or add additional context in comments.

1 Comment

I made the change but now I am getting the following error TypeError: Cannot read property 'filter' of undefined
0

I'll suggest you should use the splice method.

1 Comment

Please can you edit your answer and elaborate it, preferably with an example. Many other people, with wildly varying skill levels, will visit this question in the future and your answer would be much more valuable to those visitors if you could make it clearer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.