我正在使用复选框实现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
答案 0 :(得分:1)
对于每个checked
项目,您只有一个todo
状态。
我建议您将checked
状态添加到todos
列表中的每个项目中。
然后您可以找到项目并相应地更改状态
答案 1 :(得分:1)
您的代码有一些问题。最大的问题是您的String text =
java.text.MessageFormat.format(
"You're about to delete {0} rows.".replaceAll("'", "''"), 5);
,onDelete
和onChangeCheckbox
处理程序中的状态突变。这些处理程序还会错误地不存储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
答案 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