简体   繁体   English

反应待办事项清单,如何使此删除按钮起作用?

[英]React to do list, how do i get this delete button to work?

I have a simple to do app that is working fine, except for the ability to delete items from the list. 除了可以从列表中删除项目之外,我还有一个运行良好的简单应用程序。 I have already added the button to each of the list items. 我已经将按钮添加到每个列表项。 I know I want to use the .filter() method to pass the state a new array that doesn't have the deleted to-do but I'm not sure how to do something like this. 我知道我想使用.filter()方法将状态传递给没有删除的待办事项的新数组,但是我不确定如何做这样的事情。

Here is the App's main component: 这是应用程序的主要组件:

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(e) {
    this.setState({ })
  }

  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(index) } />
          )}
        </ul>
        <form onSubmit={ (e) => this.handleSubmit(e) }>
          <input type="text" value={ this.state.newTodoDescription } 
            onChange={ (e) => this.handleChange(e) } />
          <input type="submit" />
        </form>

      </div>
    );
  }
}

And then here is the To-Do's component: 然后是待办事项的组件:

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

Before you get any further you should never use a list index as the key for your React Elements. 在进一步了解之前,切勿使用列表索引作为React Elements的键。 Give your ToDo an id and use that as the key. 给您的待办事项ID,并将其用作密钥。 Sometimes you can get away with this but when you are deleting things it will almost always cause issues. 有时您可以避免这种情况,但是在删除内容时,几乎总是会引起问题。

https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318 https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

If you don't want to read the article, just know this 如果您不想阅读文章,请知道这一点

Let me explain, a key is the only thing React uses to identify DOM elements. 让我解释一下,密钥是React用来标识DOM元素的唯一东西。 What happens if you push an item to the list or remove something in the middle? 如果将项目推送到列表或在中间删除某些内容,会发生什么? If the key is same as before React assumes that the DOM element represents the same component as before. 如果密钥与之前相同,则React假定DOM元素表示与以前相同的组件。 But that is no longer true. 但这不再是真的。

On another note, add an onClick to your button and pass the function you want it to run as a prop from App. 另外请注意,将onClick添加到您的按钮并传递您希望其作为App中的道具运行的功能。

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

and App.js 和App.js

...

constructor(props) {
  ...
  this.handleClick = this.handleClick.bind(this);
}

handleClick(id) {
  // Do stuff
}

<ToDo
  ...
  handleClick={this.handleClick}
/>

Event handlers to the rescue: 抢救事件处理程序

You can send onDelete prop to each ToDo : 您可以将onDelete发送给每个ToDo

const Todo = ({ description, id, isCompleted, toggleComplete, onDelete }) => 
  <li>
    <input
      type="checkbox"
      checked={isCompleted} 
      onChange={toggleComplete}
    />
    <button onClick={() => onDelete(id)}>Destroy!</button>
    <span>{description}</span>
  </li>

And from App : 而从App

<ToDo 
  // other props here
  onDelete={this.deleteTodo}
/>

As pointed by @Dakota, using index as key while mapping through a list is not a good pattern. 正如@Dakota指出的那样,在通过列表进行映射时使用索引作为键不是一个好的模式。

Maybe just change your initialState and set an id to each one of them: 也许只需更改您的initialState并为其设置一个id

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 also makes life easier to delete an item from the array: 这也使从数组中删除项目变得更容易:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我正在尝试在 express 中构建一个简单的待办事项列表,但我无法使用“删除”按钮 - I'm trying to build a simple To Do list in express, but I can't get my 'delete' button to work 如何获得删除按钮以删除单行? - How do I get my delete button to delete a single row? 如何让复选框与 React 一起使用? - How do I get checkboxes to work with React? 如何使用“清除”按钮删除列表项? (javascript) - How do I delete list items with “clear” button? (javascript) 如何间隔复选框,列表和删除按钮 - How do I space out the the checkbox, list and delete button 如何使用上下文 API 删除 React js 中的列表 - How do I delete a list in React js using Context API 我如何通过道具来获取取消按钮以在Redux-Form上的React中工作 - How do I pass props to get a cancel button to work in React on a Redux-Form 如何让我的删除 function 在 Vue JS 中工作? - How do I get my delete function to work in Vue JS? 如何使同样使用列表项创建的按钮起作用? 我希望它删除数组的当前项。 每个项目都有自己的按钮 - How do i make the button that's also created with the list item work? I want it to delete the current item of the array. Each item has it own button 如何使多个功能在单击按钮时起作用? - How Do I Get Multiple Functions to Work onclick for a Button?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM