我有一个简单的做应用程序,是很好的工作,除了删除的能力,从列表中的项目。我已经将按钮添加到每个列表项中。我知道我希望使用.filter()方法来传递状态--一个没有删除待办事项的新数组,但我不知道如何执行这样的操作。
以下是应用程序的主要组件:
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>
);
}
}
发布于 2017-11-21 13:34:18
事件处理程序到救援:
您可以将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>
来自App
:
<ToDo
// other props here
onDelete={this.deleteTodo}
/>
正如@Dakota所指出的,在通过列表进行映射时使用索引作为键并不是一种好的模式。
也许只需更改您的initialState
并为其中每一个设置一个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),
}))
}
发布于 2017-11-21 13:33:23
在更进一步之前,您不应该使用列表索引作为您的React元素的键。给您的ToDo一个id并使用它作为密钥。有时候,你可以逃脱这个问题,但是当你删除一些东西时,它几乎总是会引起问题。
https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318
如果你不想读这篇文章,只要知道这一点
让我解释一下,键是唯一用于识别DOM元素的React。如果您将项目推入列表或删除中间的某个内容,会发生什么情况?如果键与前面相同,React假设DOM元素表示与前面相同的组件。但这已不再是事实。
在另一个注意事项上,添加一个onClick到您的按钮,并传递函数,您希望它运行作为一个道具从应用程序。
<button onClick={() => this.props.handleClick(this.props.id)} />
和App.js
...
constructor(props) {
...
this.handleClick = this.handleClick.bind(this);
}
handleClick(id) {
// Do stuff
}
<ToDo
...
handleClick={this.handleClick}
/>
https://stackoverflow.com/questions/47422915
复制相似问题