复选框在反应 js 中的待办事项中不起作用

我正在使用复选框实现 Todo。我在该州有一个 id、content、status 属性。Status 有 3 种状态(pending、done、deleted)。待办事项列表有一个复选框。如果状态为待定,则不应选中复选框。如果状态为完成,则应选中复选框。默认情况下,状态为待定。应根据状态选中/取消选中复选框。在删除待办事项时,状态应更新为已删除。现在我对复选框的实现感到震惊。它没有按照要求工作。


应用程序.js:


import React from 'react';

import Todo from './Todo';

import AddTodo from './AddTodo';


class App extends React.Component{

  state={

   todos:[

   {id:1,content:'Buy milk1',status:'pending'},

   {id:2, content:'buy carrots1', status: 'pending'},

   {id:3,content:'Buy milk2',status:'done'},

   {id:4, content:'buy carrots2', status: 'deleted'}

  ]

}

onDelete=(id)=>{

 const todo = this.state.todos.find((todoItem => todoItem.id === id))

 todo.status ='deleted';

 this.setState([...this.state.todos]);

}

onChangeCheckbox=(id, checked)=>{ 

 const todo = this.state.todos.find((todoItem => todoItem.id === id))

 if(checked){

  todo.status = 'done'

 }

 else{

  todo.status = 'pending'

 }

 this.setState([...this.state.todos]);

 }

addTodo=(todo)=>{

 todo.id=Math.random();

 todo.status = "pending";

 let todos=[...this.state.todos,todo];

 this.setState({todos});

}

render(){

 return(

  <div>

    <h1>Todo's App</h1>

    

    <AddTodo addTodo={this.addTodo} />

    <Todo todos={this.state.todos} deleteTodo={this.onDelete} onChangeCheckbox= 

    {this.onChangeCheckbox} />

   </div>

  )

 }

}


export default App;


繁花如伊
浏览 129回答 3
3回答

慕村9548890

您的代码存在一些问题。onDelete最大的问题是您的、onChangeCheckbox和处理程序中的状态突变addTodo。这些处理程序也不正确地不存储todos数组。使用功能状态更新并将现有状态 todos 数组映射到新数组,并复制todo与 id 匹配的项目,这样您就不会改变状态对象。Math.random 生成浮点数,因此很难与===. 我改为为每个添加一个 guid。class App extends React.Component {&nbsp; state = {&nbsp; &nbsp; todos: [&nbsp; &nbsp; &nbsp; { id: uuidV4(), content: "Buy milk1", status: "pending" },&nbsp; &nbsp; &nbsp; { id: uuidV4(), content: "buy carrots1", status: "pending" },&nbsp; &nbsp; &nbsp; { id: uuidV4(), content: "Buy milk2", status: "done" },&nbsp; &nbsp; &nbsp; { id: uuidV4(), content: "buy carrots2", status: "deleted" }&nbsp; &nbsp; ]&nbsp; };&nbsp; onDelete = (id) => {&nbsp; &nbsp; this.setState((prevState) => ({&nbsp; &nbsp; &nbsp; todos: prevState.todos.map((todo) =>&nbsp; &nbsp; &nbsp; &nbsp; todo.id === id&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...todo,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; status: "deleted"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : todo&nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; }));&nbsp; };&nbsp; onChangeCheckbox = (id, checked) => {&nbsp; &nbsp; this.setState((prevState) => ({&nbsp; &nbsp; &nbsp; todos: prevState.todos.map((todo) =>&nbsp; &nbsp; &nbsp; &nbsp; todo.id === id&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...todo,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; status: checked ? "done" : "pending"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : todo&nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; }));&nbsp; };&nbsp; addTodo = (todo) => {&nbsp; &nbsp; this.setState((prevState) => ({&nbsp; &nbsp; &nbsp; todos: [&nbsp; &nbsp; &nbsp; &nbsp; ...prevState.todos,&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...todo,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; id: uuidV4(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; status: "pending"&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; }));&nbsp; };&nbsp; render() {&nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; &nbsp; <h1>Todo's App</h1>&nbsp; &nbsp; &nbsp; &nbsp; <AddTodo addTodo={this.addTodo} />&nbsp; &nbsp; &nbsp; &nbsp; <Todo&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; todos={this.state.todos}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deleteTodo={this.onDelete}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onChangeCheckbox={this.onChangeCheckbox}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; );&nbsp; }}也不需要存储任何checked状态,Todo.js因为检查状态很容易从您的todo.status财产中派生出来。如果状态为“完成”,则选中该框。todos您可以(应该)首先通过过滤器运行您的数组以删除已删除的状态待办事项。const Todo = ({ todos, deleteTodo, onChangeCheckbox }) => {&nbsp; const todoList = todos.length ? (&nbsp; &nbsp; todos&nbsp; &nbsp; &nbsp; .filter(({ status }) => status !== "deleted")&nbsp; &nbsp; &nbsp; .map((todo) => {&nbsp; &nbsp; &nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <div key={todo.id}>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <input&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; type="checkbox"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; checked={todo.status === "done"}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onChange={(event) =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onChangeCheckbox(todo.id, event.target.checked)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <p&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; style={&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; todo.status === "pending"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? { color: "red" }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : { color: "green", textDecoration: "line-through" }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {todo.content}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <button onClick={() => deleteTodo(todo.id)}>Delete</button>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <hr />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; })&nbsp; ) : (&nbsp; &nbsp; <p>You have no todos</p>&nbsp; );&nbsp; return <div>{todoList}</div>;};

回首忆惘然

checked对于每个项目,您只有一个状态todo。我建议您为列表checked中的每个项目添加状态todos。然后你可以找到项目并相应地改变状态

慕工程0101907

发生这种情况是因为您让选中状态监听current component state而不是项目状态。而且它们不同步。所以你有两个解决方案。首先将状态值作为道具传递给已检查状态,以便在状态值更新时让状态发生变化,我认为它更昂贵。我有其他完全没有状态的建议。&nbsp;// const [checked, setChecked] = useState(false); remove that, you no longer need it&nbsp;const handleInputChange =(event,id,status)=>{&nbsp;&nbsp; &nbsp;let isChecked = status=='pending' ? true: false;&nbsp; &nbsp;onChangeCheckbox(id, isChecked);&nbsp;}同时更新输入检查状态<input&nbsp; &nbsp; type="checkbox"&nbsp; &nbsp; checked={todo.status === 'pending' ? false : true}&nbsp; &nbsp; onChange= {(event)=>handleInputChange(event,todo.id,todo.status)}&nbsp;/>https://codesandbox.io/s/competent-hugle-jn22o?file=/src/Todo.js
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript