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
添加回答
舉報