简体   繁体   中英

Trying to get my delete button to work on a React Component

I'm working on my First project with React, I have an App and a ToDo. I am defining a deleteToDo method and I want the method to call this.setState() and pass it a new array that doesn't have the to-do item being deleted with the use of the .filter() array method. I don't want to alter the code to much or introduce more complexity. In essence I would like to keep it as straight forward as possible. I am still a beginner with React so this has been a big learning process. I feel that I am close.

This is the main app

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: [
         { description: 'Walk the cat', isCompleted: true },
         { description: 'Throw the dishes away', isCompleted: false },
         { description: 'Buy new dishes', isCompleted: false }
       ],
       newTodoDescription: ''
     };
    }

    deleteToDo(index) {
       const todos = this.state.todos.slice();
       const todo = todos[index];
       todo.deleteToDo = this.state.filter(index);
         this.setState({ todos: todos });
     }   

    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 });
  }

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

export default App;

And this the ToDo aspect

 import React, { Component } from 'react';

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

  export default ToDo;

You slice and array without the index, that's may be why your delete not work

deleteToDo(index) {
    const todos = this.state.todos.slice(index, 1);
    this.setState({ todos: todos });
} 

1) You need to bind your deleteToDo method in the constructor

this.deleteToDo = this.deleteToDo.bind(this);

2) You need to set a new property on the component that is the same as its index.

<ToDo
  key={index}
  id={index}
  description={ todo.description }
  // ...
/>

3) Then you can pass that index as the argument to deleteToDo (making sure you spell the method name correctly).

<button
  type="button"
  onClick={() => this.props.deleteToDo(this.props.index)}
>Delete
</button>

4) Finally, you can strip down your deleteToDo method to the following:

deleteToDo(index) {

  // Return a new array that doesn't
  // have a row with a matching index
  const todos = this.state.todos.filter((el, i) => i !== index);
  this.setState({ todos });
}   

Here's a working version .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM