如何在 React 中删除 ToDo 项 onClick?

IT技术 reactjs
2021-05-05 04:49:36

我正在用 React 做一个简单的待办事项应用程序,只是为了练习。单击列表项时,如何删除它?

这是我的 todos.js

export default class Todos extends Component {
    constructor(props) {
        super(props);
        this.state = { todos: [], text: '' };
    }

    addTodo(e) {
        e.preventDefault();
        this.setState({ todos: [ this.state.text, ...this.state.todos ] });
        this.setState({ text: ''});
    }

    updateValue(e) {
        this.setState({ text: [e.target.value]})
    }

    render() {
        return(
            <div>
                <form onSubmit = {(e) => this.addTodo(e)}>
                    <input
                        placeholder="Add Todo"
                        value={this.state.text}
                        onChange={(e) => {this.updateValue(e)}}
                    />
                    <button type="submit">Add Todo</button>
                </form>
                <TodoList todos={this.state.todos}/>
            </div>
        );
    }
}

这是 TodoList.js,我试图从中删除列表项。

import React, { Component } from 'react';
import { connect } from 'react-redux';

export default class TodoList extends Component {
    removeItem(e) {
        // splice this.props.todos??
    }
    render() {
        return(
            <ul>
                { this.props.todos.map((todo) => {
                    return <li onClick={(e) => { this.removeItem(e)}} key={todo}>{ todo }</li>
                })}
            </ul>
        );
    }
}
4个回答

要删除待办事项,首先从父组件传递一个函数:

<TodoList todos={this.state.todos} removeTodo={this.removeTodo}/>

将此函数绑定在constructor

this.removeTodo = this.removeTodo.bind(this);

在父组件中定义此函数,它将从state变量中删除该项目

removeTodo(name){
    this.setState({
        todo: this.state.todo.filter(el => el !== name)
    })
}

然后在子组件内部调用此方法删除待办事项:

export default class TodoList extends Component {
    removeItem(e) {
        this.props.removeTodo(item);
    }
    render() {
        return(
            <ul>
                { this.props.todos.map((todo) => {
                    return <li onClick={() => { this.removeItem(todo)}} key={todo}>{ todo }</li>
                })}
            </ul>
        );
    }
}

建议:

如果要设置多个值,请不要setState在 a 内多次调用,然后像这样写:functionstate

this.setState({
    a: value1,
    b: value2,
    c: value3
})

工作示例:

更新:

这是@whs.bsmith 的疑问,我建议的代码在用户将在待办事项列表中添加唯一项目的情况下正常工作,如果他尝试添加相同的项目,它将不会反映在 ui 中,因为 OP 是使用待办事项名称作为键,键应该是唯一的。

要解决这个问题:

在工作片段中,我使用索引代替待办事项名称作为键,这将正常工作,它将允许用户多次添加相同的项目,并且在删除时,它只会删除该特定项目,而不是所有具有相同名称的项目, 但是使用索引作为key并不是一个好主意。

您已经addTodo函数中调用了setState两次您可以在单个 setState 函数中设置待办事项文本,如下所示:

addTodo(e) {
    e.preventDefault();
    this.setState({ todos: [ this.state.text, ...this.state.todos ], text: '' });
}

不要TodoList组件中编写removeItem函数,因为它纯粹是在处理props。将一个removeItem函数从Todos传递给它,并在 Todos 的 removeItem 函数中删除该项目,如下所示:

import React, {Component} from 'react'
export default class Todos extends Component {
  constructor(props) {
    super(props);
    this.state = { todos: [], text: '' };
    this.removeItem = this.removeItem.bind(this)
  }

  addTodo(e) {
    e.preventDefault();
    this.setState({ todos: [ this.state.text, ...this.state.todos ], text: '' });
  }


  updateValue(e) {
    this.setState({ text: [e.target.value]})
  }
  removeItem(index) {
    const todos = this.state.todos.filter((todo, todoIndex) => {
      return todoIndex !== index
    })
    this.setState({ todos })
  }
  render() {
    return(
      <div>
        <form onSubmit = {(e) => this.addTodo(e)}>
          <input
            placeholder="Add Todo"
            value={this.state.text}
            onChange={(e) => {this.updateValue(e)}}
            />
          <button type="submit">Add Todo</button>
        </form>
        <TodoList todos={this.state.todos} removeItem={this.removeItem} />
      </div>
    );
  }
}

class TodoList extends Component {
  render() {
    return(
      <ul>
        { this.props.todos.map((todo, index) => {
          return <li onClick={(e) => { this.props.removeItem(index)}} key={todo}>{ todo }</li>
        })}
      </ul>
    );
  }
}

希望能帮助到你。

class TodoList extend React.Component{
    constructor(props){
        super(props);
        this.state = {
            todos: [],
            todo: ''
        }
        this.changeTodo = this.changeTodo.bind(this);
        this.addTodo = this.addTodo.bind(this);
        this.removeTodo = this.removeTodo.bind(this);
    }

    changeTodo(event){
        this.setState({
            todo: event.target.value
        })
    }

    addTodo(){
        let { todo, todos } = this.state;
        this.setState({
            todo: '',
            todos: [...todos, todo]
        })
    }

    removeTodo(index){
        let { todos } = this.state;
        todos.splice(index, 1);
        this.setState({
            todos: todos
        })
    }

    render(){
        let { todo, todos } = this.state;
        return <div>
            <input value={todo} onChange={this.changeTodo}/>
            <button onClick={this.addTodo}>Add Todo</button>
            {
                todos.map((todo, index)=>{
                    return <h1 onClick={this.removeTodo.bind(undefined, index)} key={index}>{todo}</h1>
                })
            }
        </div>
    }
}

这是 TodoList 的一个小例子。通过此代码了解在您的 TodoList 应用程序中删除待办事项。

首先,您希望在 Todos 类中存在 removeItem 方法,因为这是存储状态的地方。然后,您可以使用过滤器或切片

export default class Todos extends Component {
    constructor(props) {
        super(props);
        this.state = { todos: [], text: '' };
    }

    addTodo(e) {
        e.preventDefault();
        this.setState({ todos: [ this.state.text, ...this.state.todos ] });
        this.setState({ text: ''});
    }

    updateValue(e) {
        this.setState({ text: [e.target.value]})
    }

    removeItem = index => {
        //either use filter
        const { todos } = this.state;
        const newTodos = todos.filter((todo, i) => i !== index);
        this.setState({ todos: newTodos});

        //or use slice
        const slicedNewTodos = todos.slice(0, index).concat(todos.slice(index + 1));
        this.setState({ todos: slicedNewTodos});
    }

    render() {
        return(
            <div>
                <form onSubmit = {(e) => this.addTodo(e)}>
                    <input
                        placeholder="Add Todo"
                        value={this.state.text}
                        onChange={(e) => {this.updateValue(e)}}
                    />
                    <button type="submit">Add Todo</button>
                </form>
                <TodoList removeItem={this.removeItem} todos={this.state.todos}/>
            </div>
        );
    }
}

import React, { Component } from 'react';
import { connect } from 'react-redux';

class TodoList extends Component {
    render() {
        return(
            <ul>
                { this.props.todos.map((todo, index) => {
                    return <li onClick={() => this.props.removeItem(index)} key={todo}>{ todo }</li>
                })}
            </ul>
        );
    }
}