复选框在React JS中的todo中不起作用

时间:2020-10-16 04:30:29

标签: javascript reactjs jsx

我正在使用复选框实现Todo。我在状态中有一个id,content,status属性。 状态有3种状态(待定,完成,已删除)。待办事项清单有一个复选框。如果状态为待处理,则不应选中此复选框。如果状态为完成,则应选中复选框。默认情况下,状态为未决。应根据状态选中/取消选中复选框。删除待办事项后,状态应更新为已删除。现在,我对复选框实现感到震惊。无法按照要求运行。

App.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;

AddTodo.js:

  import React from 'react';

class AddTodo extends React.Component{
  state={
    content:''
  }

 handleChange=(e)=>{
    this.setState({
        content:e.target.value
    });
 }
 handleSubmit=(e)=>{
    e.preventDefault();
    this.props.addTodo(this.state);
    this.setState({
        content:''
    })
  }
 render(){
    return(
        <div>
            <form onSubmit={this.handleSubmit}>
                <input type='text' onChange={this.handleChange} value={this.state.content} 
                 placeholder="Enter todo" />
                <input type="submit" value="Submit"/>
            </form>
        </div>
    );
  }
 }
 export default AddTodo;

Todo.js:

 import React, {useState} from 'react';

 const Todo=({todos,deleteTodo, onChangeCheckbox})=>{
   const [checked, setChecked] = useState(false);

   const handleInputChange =(event,id,status)=>{
    setChecked(status=='pending' ? !checked: checked) 
    onChangeCheckbox(id,!checked);
 }
 const todoList=todos.length ? (

    todos.map(todo=>{
        return(
            <div key={todo.id}>
                {(todo.status === 'pending' || todo.status === 'done' )&& (
                        <div>
                            {/* <input
                                type="checkbox"
                                checked={checked}
                                onChange={(event)=>handleInputChange(event,todo.id)}
                            /> */}
                            <input
                                type="checkbox"
                                checked={todo.status === 'pending' ? checked : !checked}
                                onChange= 
                         {(event)=>handleInputChange(event,todo.id,todo.status)}
                            />
                            <p style={todo.status =='pending'? {color:'red'}: 
                      {color:'green',textDecoration:'line-through'}} >
                                {todo.content}
                            </p>
                            <button onClick={()=>deleteTodo(todo.id)}>Delete</button>
                        </div>
                    )}
            </div>
        )
    })
  ):(
    <p>You have no todos</p>
  );
 return(
    <div>
        {todoList}
    </div>
  )
 }
 export default Todo;

请先谢谢。。请在此处找到codeandbox链接:https://codesandbox.io/s/awesome-ganguly-0r054?file=/src/Todo.js

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您的代码有一些问题。最大的问题是您的String text = java.text.MessageFormat.format( "You're about to delete {0} rows.".replaceAll("'", "''"), 5); onDeleteonChangeCheckbox处理程序中的状态突变。这些处理程序还会错误地不存储addTodo数组。

使用功能状态更新并将现有状态todos数组映射到新数组,并复制ID匹配的todos项,这样就不会更改状态对象。

Math.random会生成浮点数,因此, 极其 很难与todo进行比较。我给每个向导添加了一个向导。

===

也无需在class App extends React.Component { state = { todos: [ { id: uuidV4(), content: "Buy milk1", status: "pending" }, { id: uuidV4(), content: "buy carrots1", status: "pending" }, { id: uuidV4(), content: "Buy milk2", status: "done" }, { id: uuidV4(), content: "buy carrots2", status: "deleted" } ] }; onDelete = (id) => { this.setState((prevState) => ({ todos: prevState.todos.map((todo) => todo.id === id ? { ...todo, status: "deleted" } : todo ) })); }; onChangeCheckbox = (id, checked) => { this.setState((prevState) => ({ todos: prevState.todos.map((todo) => todo.id === id ? { ...todo, status: checked ? "done" : "pending" } : todo ) })); }; addTodo = (todo) => { this.setState((prevState) => ({ todos: [ ...prevState.todos, { ...todo, id: uuidV4(), status: "pending" } ] })); }; render() { return ( <div> <h1>Todo's App</h1> <AddTodo addTodo={this.addTodo} /> <Todo todos={this.state.todos} deleteTodo={this.onDelete} onChangeCheckbox={this.onChangeCheckbox} /> </div> ); } } 中存储任何checked状态,因为已检查状态很容易从您的Todo.js属性中派生。如果状态为“完成”,则选中该框。

您可以(应该)首先通过过滤器运行todo.status数组,以删除已删除的状态待办事项。

todos

Edit checkboxes-are-not-working-in-todo-in-react-js

答案 2 :(得分:1)

之所以发生这种情况,是因为您让选中状态监听了current component state而不是项目状态。并且它们不同步。所以您有两种解决方案。首先将状态值传递给已检查状态,以便在状态值更新时让状态发生变化,我认为这更昂贵。我还有其他建议,完全没有状态。

 // const [checked, setChecked] = useState(false); remove that, you no longer need it

 const handleInputChange =(event,id,status)=>{ 
   let isChecked = status=='pending' ? true: false;
   onChangeCheckbox(id, isChecked);
 }

还更新输入检查状态

<input
    type="checkbox"
    checked={todo.status === 'pending' ? false : true}
    onChange= {(event)=>handleInputChange(event,todo.id,todo.status)}
 />

https://codesandbox.io/s/competent-hugle-jn22o?file=/src/Todo.js