3 回答
TA贡献1884条经验 获得超4个赞
您的代码存在一些问题。onDelete最大的问题是您的、onChangeCheckbox和处理程序中的状态突变addTodo。这些处理程序也不正确地不存储todos数组。
使用功能状态更新并将现有状态 todos 数组映射到新数组,并复制todo与 id 匹配的项目,这样您就不会改变状态对象。
Math.random 生成浮点数,因此很难与===. 我改为为每个添加一个 guid。
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您可以(应该)首先通过过滤器运行您的数组以删除已删除的状态待办事项。
const Todo = ({ todos, deleteTodo, onChangeCheckbox }) => {
const todoList = todos.length ? (
todos
.filter(({ status }) => status !== "deleted")
.map((todo) => {
return (
<div key={todo.id}>
<div>
<input
type="checkbox"
checked={todo.status === "done"}
onChange={(event) =>
onChangeCheckbox(todo.id, event.target.checked)
}
/>
<p
style={
todo.status === "pending"
? { color: "red" }
: { color: "green", textDecoration: "line-through" }
}
>
{todo.content}
</p>
<button onClick={() => deleteTodo(todo.id)}>Delete</button>
</div>
<hr />
</div>
);
})
) : (
<p>You have no todos</p>
);
return <div>{todoList}</div>;
};
TA贡献1887条经验 获得超5个赞
发生这种情况是因为您让选中状态监听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
添加回答
举报