我正在为我正在学习的课程做一个教程。我正在做的实验是创建一个待办事项应用程序。我正在进行第三步,这一步要求我们创建一个删除任务的按钮。我觉得很可笑,因为我知道我可以解决这个问题,但是... a a.嗯,我还没有!我将发布代码,看看是否有任何初始问题。然后用我已经尝试过的方法更新。任何帮助都是非常感谢的。谢谢!
import React, { useState } from "react";
import "./App.css";
const App = () => {
const [todos, setTodos] = useState([]);
const [todo, setTodo] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
const newTodo = {
id: new Date().getTime(),
text: todo.trim(),
completed: false,
};
if (newTodo.text.length > 0) {
setTodos([...todos].concat(newTodo));
setTodo("");
} else {
alert("Enter Valid Task");
setTodo("");
}
}
const deleteTodo = (id) => {
let updatedTodos = [...todos].filter((todo) => todo.id !== id);
setTodos(updatedTodos);
}
const button = <button onClick={() => deleteTodo(todo.id)}>Delete</button>
return (
<div>
<h1>To-do List</h1>
<form onSubmit={handleSubmit}>
<input
type="text"
onChange={(e) => setTodo(e.target.value)}
placeholder="Add a new task"
value={todo}
/>
<button type="submit">Add Todo</button>
</form>
{todos.map((todo) => <div>ID: {todo.id} Task: {todo.text} {button}</div>)}
</div>
);
};
export default App;
我不只是复制和粘贴,所以有可能我在输入时搞砸了一些东西。我希望deleteTodo()函数接受一个todo.id,并过滤待办事项列表,排除我想删除的。我想这个问题可能是由我创建按钮的方式引起的?同样,我不知道为什么我不能弄清楚。TIA。
编辑:好的,现在可以了!非常感谢你们所有人的解释。对于其他遇到这个问题的人,这里是我的失误之处:
const button = <button onClick={() => deleteTodo(todo.id)}Delete<button>
@Nicholas Tower的解释非常清楚--在.map(...)
之外创建这个函数会导致deleteTodo获取todo state,而不是我希望它从todos
数组中删除的not todo。@Lars Vonk、@0stone0和@Sudip Shrestha都说过这一点。@Sudip Shrestha和@pilchard还帮助更正了deleteTodo函数。同样,我真的很感谢所有的帮助。代码现在工作。我将显示更新,以便人们有类似的问题可以比较:
import React from "react";
import "./App.css";
const App = () => {
const [todos, setTodos] = React.useState([]);
const [todo, setTodo] = React.useState("");
const handleSubmit = (e) => {
e.preventDefault();
const newTodo = {
id: new Date().getTime(),
text: todo.trim(),
completed: false,
};
if (newTodo.text.length > 0) {
setTodos(todos.concat(newTodo));
setTodo("");
} else {
alert("Enter a valid task");
setTodo("");
}
}
// update the state using setState, rathar than mutating it directly @Sudip Shrestha
const deleteTodo = id => {
setTodos(prevState => {
return prevState.filter(todo => todo.id !== id)
});
};
// line 51: button placed inside .map(), as per many suggestions below.
return (
<>
<h1>Todo List</h1>
<form onSubmit={handleSubmit}>
<input
type="text"
onChange={(e) => setTodo(e.target.value)}
placeholder="Add a new task..."
value={todo}
/>
</form>
{todos.map((todo) =>
<div>
ID: {todo.id} Task: {todo.text}
<button onClick={() => deleteTodo(todo.id)}>Delete</button>
</div>)}
</>
);
};
export default App;
6条答案
按热度按时间ee7vknir1#
这个button元素只创建了一次,它引用的
todo
变量是todo状态,它是一个字符串(通常是空字符串),因为todo
是字符串,todo.id
就是undefined
,deleteTodo
不能对它做任何事情。您需要为每个项目创建单独的按钮,因此应该将以下代码向下移动到
.map
中:现在每个元素都有了自己的按钮和onClick函数,在这些函数中,
todo
是数组中的元素。tjrkku2a2#
按钮无法访问它具有的todo,我认为您应该将代码从
const button
放到您引用它的位置,或者将其更改为const button = (todo) => <button onClick={ () => deleteTodo(todo.id); }>Delete</button>
,然后通过执行{button()}
访问它kse8i1jr3#
它对每个todo都有相同的回调,你应该把它移到你的
map
里面,这样todo.id
就可以引用map()
的迭代器:更新的演示:
一个二个一个一个
ovfsdjhp4#
试试这个:
然后在Map上
这样,"删除待办事项"按钮将绑定到特定的待办事项ID,避免绑定到应用程序中
todo
的当前值。nqwrtyyt5#
1.最好使用***setState***更新状态。直接禁用状态会破坏React数据流的主要原则(单向),使您的应用非常脆弱,基本上忽略了整个组件生命周期。
1.另外,您需要将***delete***从字符串更改为函数,并传递id或将jsx直接放置在map函数中。
ma8fv8wu6#
问题出现在:
您可以使用
之后就这样叫吧