Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对任务列表作出反应,如何使此删除按钮工作?_Javascript_Reactjs - Fatal编程技术网

Javascript 对任务列表作出反应,如何使此删除按钮工作?

Javascript 对任务列表作出反应,如何使此删除按钮工作?,javascript,reactjs,Javascript,Reactjs,我有一个简单易用的应用程序,除了能够从列表中删除项目外,它运行良好。我已经将按钮添加到每个列表项中。我知道我想使用.filter()方法向状态传递一个没有已删除待办事项的新数组,但我不确定如何执行类似操作 以下是该应用程序的主要组件: class App extends Component { constructor(props){ super(props); this.state = { todos: [ { description: 'Walk

我有一个简单易用的应用程序,除了能够从列表中删除项目外,它运行良好。我已经将按钮添加到每个列表项中。我知道我想使用.filter()方法向状态传递一个没有已删除待办事项的新数组,但我不确定如何执行类似操作

以下是该应用程序的主要组件:

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>
    );
  }
}
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>
    );
  }
}
类应用程序扩展组件{
建造师(道具){
超级(道具);
此.state={
待办事项:[
{说明:'遛猫',已完成:正确},
{说明:'把盘子扔掉',已完成:错误},
{说明:'买新菜',已完成:错误}
],
新密码说明:“”
};
}
删除TODO(e){
this.setState({})
}
手变(e){
this.setState({newTodoDescription:e.target.value})
}
handleSubmit(e){
e、 预防默认值();
如果(!this.state.newTodoDescription){return}
const newTodo={description:this.state.newTodoDescription,
isCompleted:false};
this.setState({todos:[…this.state.todos,newTodo],
newTodoDescription:''});
}
切换完成(索引){
const todos=this.state.todos.slice();
常数todo=todo[索引];
todo.isCompleted=todo.isCompleted?false:true;
this.setState({todos:todos});
}
render(){
返回(
    {this.state.todos.map((todo,index)=> this.toggleComplete(index)}/> )}
此.handleSubmit(e)}> this.handleChange(e)}/> ); } }
下面是待办事项的组成部分:

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>
    );
  }
}
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>
    );
  }
}
类ToDo扩展组件{
render(){
返回(
  • 毁灭! {this.props.description}
  • ); } }
    在进一步了解之前,决不能使用列表索引作为元素的键。给ToDo一个id,并将其用作密钥。有时你可以不受惩罚,但当你删除东西时,它几乎总是会引起问题

    如果你不想读这篇文章,就知道这一点

    让我解释一下,键是React用来标识DOM的唯一东西 元素。如果将项目推送到列表或删除,会发生什么情况 中间有东西吗?如果钥匙与之前的相同,则假定 DOM元素表示与前面相同的组件。但那 这不再是事实

    另一方面,在按钮上添加一个onClick,并从应用程序中传递希望它作为道具运行的函数

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

    ...
    
    constructor(props) {
      ...
      this.handleClick = this.handleClick.bind(this);
    }
    
    handleClick(id) {
      // Do stuff
    }
    
    <ToDo
      ...
      handleClick={this.handleClick}
    />
    
    。。。
    建造师(道具){
    ...
    this.handleClick=this.handleClick.bind(this);
    }
    handleClick(id){
    //做事
    }
    
    在进一步了解之前,决不能使用列表索引作为元素的键。给ToDo一个id,并将其用作密钥。有时你可以不受惩罚,但当你删除东西时,它几乎总是会引起问题

    如果你不想读这篇文章,就知道这一点

    让我解释一下,键是React用来标识DOM的唯一东西 元素。如果将项目推送到列表或删除,会发生什么情况 中间有东西吗?如果钥匙与之前的相同,则假定 DOM元素表示与前面相同的组件。但那 这不再是事实

    另一方面,在按钮上添加一个onClick,并从应用程序中传递希望它作为道具运行的函数

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

    ...
    
    constructor(props) {
      ...
      this.handleClick = this.handleClick.bind(this);
    }
    
    handleClick(id) {
      // Do stuff
    }
    
    <ToDo
      ...
      handleClick={this.handleClick}
    />
    
    。。。
    建造师(道具){
    ...
    this.handleClick=this.handleClick.bind(this);
    }
    handleClick(id){
    //做事
    }
    
    救援:

    您可以将
    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>
    
    正如@Dakota所指出的,在映射列表时使用索引作为键不是一种好模式

    也许只需更改您的
    初始状态
    ,并为它们中的每一个设置
    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: '',
    }
    
    这也使从阵列中删除项目变得更容易:

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

    您可以将
    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>
    
    正如@Dakota所指出的,在映射列表时使用索引作为键不是一种好模式

    也许只需更改您的
    初始状态
    ,并为它们中的每一个设置
    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: '',
    }
    
    这也使从阵列中删除项目变得更容易:

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

    这是有道理的,但每当我更改代码时,它都会给我一个错误:const Todo=({description,id,isCompleted,toggleComplete,onDelete})=>@db22797,我只是将
    Todo
    作为无状态组件编写。检查您的babel配置,或者您可以保持您编写的方式。只需添加
    id
    onDelete
    道具,您应该会很好:)这是有道理的,但每当我更改代码时,它都会给我一个错误:const Todo=({description,id,isCompleted,toggleComplete,onDelete}=>@db22797我只是将
    Todo
    作为一个无状态组件编写。检查您的babel配置,或者您可以保持您编写的方式。只需添加
    id
    onDelete
    道具,就可以了:)