Javascript 对任务列表作出反应,如何使此删除按钮工作?
我有一个简单易用的应用程序,除了能够从列表中删除项目外,它运行良好。我已经将按钮添加到每个列表项中。我知道我想使用.filter()方法向状态传递一个没有已删除待办事项的新数组,但我不确定如何执行类似操作 以下是该应用程序的主要组件:Javascript 对任务列表作出反应,如何使此删除按钮工作?,javascript,reactjs,Javascript,Reactjs,我有一个简单易用的应用程序,除了能够从列表中删除项目外,它运行良好。我已经将按钮添加到每个列表项中。我知道我想使用.filter()方法向状态传递一个没有已删除待办事项的新数组,但我不确定如何执行类似操作 以下是该应用程序的主要组件: class App extends Component { constructor(props){ super(props); this.state = { todos: [ { description: 'Walk
class App extends Component {
constructor(props){
super(props);
this.state = {
todos: [
{ description: 'Walk the cat', isCompleted: true },
{ description: 'Throw the dishes away', isCompleted: false },
{ description: 'Buy new dishes', isCompleted: false }
],
newTodoDescription: ''
};
}
deleteTodo(e) {
this.setState({ })
}
handleChange(e) {
this.setState({ newTodoDescription: e.target.value })
}
handleSubmit(e) {
e.preventDefault();
if (!this.state.newTodoDescription) { return }
const newTodo = { description: this.state.newTodoDescription,
isCompleted: false };
this.setState({ todos: [...this.state.todos, newTodo],
newTodoDescription: '' });
}
toggleComplete(index) {
const todos = this.state.todos.slice();
const todo = todos[index];
todo.isCompleted = todo.isCompleted ? false : true;
this.setState({ todos: todos });
}
render() {
return (
<div className="App">
<ul>
{ this.state.todos.map( (todo, index) =>
<ToDo key={ index } description={ todo.description }
isCompleted={ todo.isCompleted } toggleComplete={ () =>
this.toggleComplete(index) } />
)}
</ul>
<form onSubmit={ (e) => this.handleSubmit(e) }>
<input type="text" value={ this.state.newTodoDescription }
onChange={ (e) => this.handleChange(e) } />
<input type="submit" />
</form>
</div>
);
}
}
class ToDo extends Component {
render() {
return (
<li>
<input type="checkbox" checked={ this.props.isCompleted }
onChange={ this.props.toggleComplete } />
<button>Destroy!</button>
<span>{ this.props.description }</span>
</li>
);
}
}
类应用程序扩展组件{
建造师(道具){
超级(道具);
此.state={
待办事项:[
{说明:'遛猫',已完成:正确},
{说明:'把盘子扔掉',已完成:错误},
{说明:'买新菜',已完成:错误}
],
新密码说明:“”
};
}
删除TODO(e){
this.setState({})
}
手变(e){
this.setState({newTodoDescription:e.target.value})
}
handleSubmit(e){
e、 预防默认值();
如果(!this.state.newTodoDescription){return}
const newTodo={description:this.state.newTodoDescription,
isCompleted:false};
this.setState({todos:[…this.state.todos,newTodo],
newTodoDescription:''});
}
切换完成(索引){
const todos=this.state.todos.slice();
常数todo=todo[索引];
todo.isCompleted=todo.isCompleted?false:true;
this.setState({todos:todos});
}
render(){
返回(
{this.state.todos.map((todo,index)=>
this.toggleComplete(index)}/>
)}
此.handleSubmit(e)}>
this.handleChange(e)}/>
);
}
}
下面是待办事项的组成部分:
class App extends Component {
constructor(props){
super(props);
this.state = {
todos: [
{ description: 'Walk the cat', isCompleted: true },
{ description: 'Throw the dishes away', isCompleted: false },
{ description: 'Buy new dishes', isCompleted: false }
],
newTodoDescription: ''
};
}
deleteTodo(e) {
this.setState({ })
}
handleChange(e) {
this.setState({ newTodoDescription: e.target.value })
}
handleSubmit(e) {
e.preventDefault();
if (!this.state.newTodoDescription) { return }
const newTodo = { description: this.state.newTodoDescription,
isCompleted: false };
this.setState({ todos: [...this.state.todos, newTodo],
newTodoDescription: '' });
}
toggleComplete(index) {
const todos = this.state.todos.slice();
const todo = todos[index];
todo.isCompleted = todo.isCompleted ? false : true;
this.setState({ todos: todos });
}
render() {
return (
<div className="App">
<ul>
{ this.state.todos.map( (todo, index) =>
<ToDo key={ index } description={ todo.description }
isCompleted={ todo.isCompleted } toggleComplete={ () =>
this.toggleComplete(index) } />
)}
</ul>
<form onSubmit={ (e) => this.handleSubmit(e) }>
<input type="text" value={ this.state.newTodoDescription }
onChange={ (e) => this.handleChange(e) } />
<input type="submit" />
</form>
</div>
);
}
}
class ToDo extends Component {
render() {
return (
<li>
<input type="checkbox" checked={ this.props.isCompleted }
onChange={ this.props.toggleComplete } />
<button>Destroy!</button>
<span>{ this.props.description }</span>
</li>
);
}
}
类ToDo扩展组件{
render(){
返回(
毁灭!
{this.props.description}
);
}
}
在进一步了解之前,决不能使用列表索引作为元素的键。给ToDo一个id,并将其用作密钥。有时你可以不受惩罚,但当你删除东西时,它几乎总是会引起问题
如果你不想读这篇文章,就知道这一点
让我解释一下,键是React用来标识DOM的唯一东西
元素。如果将项目推送到列表或删除,会发生什么情况
中间有东西吗?如果钥匙与之前的相同,则假定
DOM元素表示与前面相同的组件。但那
这不再是事实
另一方面,在按钮上添加一个onClick,并从应用程序中传递希望它作为道具运行的函数
<button onClick={() => this.props.handleClick(this.props.id)} />
this.props.handleClick(this.props.id)}/>
和App.js
...
constructor(props) {
...
this.handleClick = this.handleClick.bind(this);
}
handleClick(id) {
// Do stuff
}
<ToDo
...
handleClick={this.handleClick}
/>
。。。
建造师(道具){
...
this.handleClick=this.handleClick.bind(this);
}
handleClick(id){
//做事
}
在进一步了解之前,决不能使用列表索引作为元素的键。给ToDo一个id,并将其用作密钥。有时你可以不受惩罚,但当你删除东西时,它几乎总是会引起问题
如果你不想读这篇文章,就知道这一点
让我解释一下,键是React用来标识DOM的唯一东西
元素。如果将项目推送到列表或删除,会发生什么情况
中间有东西吗?如果钥匙与之前的相同,则假定
DOM元素表示与前面相同的组件。但那
这不再是事实
另一方面,在按钮上添加一个onClick,并从应用程序中传递希望它作为道具运行的函数
<button onClick={() => this.props.handleClick(this.props.id)} />
this.props.handleClick(this.props.id)}/>
和App.js
...
constructor(props) {
...
this.handleClick = this.handleClick.bind(this);
}
handleClick(id) {
// Do stuff
}
<ToDo
...
handleClick={this.handleClick}
/>
。。。
建造师(道具){
...
this.handleClick=this.handleClick.bind(this);
}
handleClick(id){
//做事
}
救援:
您可以将onDelete
道具发送到每个ToDo
:
const Todo = ({ description, id, isCompleted, toggleComplete, onDelete }) =>
<li>
<input
type="checkbox"
checked={isCompleted}
onChange={toggleComplete}
/>
<button onClick={() => onDelete(id)}>Destroy!</button>
<span>{description}</span>
</li>
正如@Dakota所指出的,在映射列表时使用索引作为键不是一种好模式
也许只需更改您的初始状态
,并为它们中的每一个设置id
:
this.state = {
todos: [
{ id: 1, description: 'Walk the cat', isCompleted: true },
{ id: 2, description: 'Throw the dishes away', isCompleted: false },
{ id: 3, description: 'Buy new dishes', isCompleted: false }
],
newTodoDescription: '',
}
这也使从阵列中删除项目变得更容易:
deleteTodo(id) {
this.setState((prevState) => ({
items: prevState.items.filter(item => item.id !== id),
}))
}
营救:
您可以将onDelete
道具发送到每个ToDo
:
const Todo = ({ description, id, isCompleted, toggleComplete, onDelete }) =>
<li>
<input
type="checkbox"
checked={isCompleted}
onChange={toggleComplete}
/>
<button onClick={() => onDelete(id)}>Destroy!</button>
<span>{description}</span>
</li>
正如@Dakota所指出的,在映射列表时使用索引作为键不是一种好模式
也许只需更改您的初始状态
,并为它们中的每一个设置id
:
this.state = {
todos: [
{ id: 1, description: 'Walk the cat', isCompleted: true },
{ id: 2, description: 'Throw the dishes away', isCompleted: false },
{ id: 3, description: 'Buy new dishes', isCompleted: false }
],
newTodoDescription: '',
}
这也使从阵列中删除项目变得更容易:
deleteTodo(id) {
this.setState((prevState) => ({
items: prevState.items.filter(item => item.id !== id),
}))
}
这是有道理的,但每当我更改代码时,它都会给我一个错误:const Todo=({description,id,isCompleted,toggleComplete,onDelete})=>@db22797,我只是将
Todo
作为无状态组件编写。检查您的babel配置,或者您可以保持您编写的方式。只需添加id
和onDelete
道具,您应该会很好:)这是有道理的,但每当我更改代码时,它都会给我一个错误:const Todo=({description,id,isCompleted,toggleComplete,onDelete}=>@db22797我只是将Todo
作为一个无状态组件编写。检查您的babel配置,或者您可以保持您编写的方式。只需添加id
和onDelete
道具,就可以了:)