我正在用React做一个简单的待办应用程序,只是为了练习。单击列表后如何删除列表项?
这是我的todos.js
export default class Todos extends Component { constructor(props) { super(props); this.state = { todos: [], text: '' }; } addTodo(e) { e.preventDefault(); this.setState({ todos: [ this.state.text, ...this.state.todos ] }); this.setState({ text: ''}); } updateValue(e) { this.setState({ text: [e.target.value]}) } render() { return( <div> <form onSubmit = {(e) => this.addTodo(e)}> <input placeholder="Add Todo" value={this.state.text} onChange={(e) => {this.updateValue(e)}} /> <button type="submit">Add Todo</button> </form> <TodoList todos={this.state.todos}/> </div> ); } }
这是TodoList.js,我正在尝试从中删除列表项。
import React, { Component } from 'react'; import { connect } from 'react-redux'; export default class TodoList extends Component { removeItem(e) { // splice this.props.todos?? } render() { return( <ul> { this.props.todos.map((todo) => { return <li onClick={(e) => { this.removeItem(e)}} key={todo}>{ todo }</li> })} </ul> ); } }
要删除待办事项,请首先从父组件传递一个函数:
<TodoList todos={this.state.todos} removeTodo={this.removeTodo}/>
将此功能绑定到constructor:
constructor
this.removeTodo = this.removeTodo.bind(this);
在父组件中定义此函数,它将从state变量中删除该项目:
state
removeTodo(name){ this.setState({ todo: this.state.todo.filter(el => el !== name) }) }
然后在子组件内部调用此方法删除待办事项:
export default class TodoList extends Component { removeItem(e) { this.props.removeTodo(item); } render() { return( <ul> { this.props.todos.map((todo) => { return <li onClick={() => { this.removeItem(todo)}} key={todo}>{ todo }</li> })} </ul> ); } }
建议:
如果要设置多个值,请不要setState在a内多次调用,然后这样编写:function``state
setState
function``state
this.setState({ a: value1, b: value2, c: value3 })
工作示例:
class Todos extends React.Component { constructor(props) { super(props); this.state = { todos: [], text: '' }; this.removeTodo = this.removeTodo.bind(this); } addTodo(e) { e.preventDefault(); this.setState({ todos: [ this.state.text, ...this.state.todos ], text: '' }); } removeTodo(name, i){ let todos = this.state.todos.slice(); todos.splice(i, 1); this.setState({ todos }); } updateValue(e) { this.setState({ text: e.target.value}) } render() { return( <div> <form onSubmit = {(e) => this.addTodo(e)}> <input placeholder="Add Todo" value={this.state.text} onChange={(e) => {this.updateValue(e)}} /> <button type="submit">Add Todo</button> </form> <TodoList todos={this.state.todos} removeTodo={this.removeTodo}/> </div> ); } } class TodoList extends React.Component { removeItem(item, i) { this.props.removeTodo(item, i); } render() { return( <ul> { this.props.todos.map((todo,i) => { return <li onClick={() => { this.removeItem(todo, i)}} key={i}>{ todo }</li> })} </ul> ); } } ReactDOM.render(<Todos/>, document.getElementById('app')) <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id='app'/>
更新:
这是针对@ whs.bsmith的疑问,我建议的代码在用户将待办事项列表中添加唯一项的情况下会正常工作,如果他尝试添加相同的项,则它不会反映在ui中,因为OP是使用待办事项名称作为关键字,关键字应该是唯一的。
要解决该问题:
在工作片段中,我使用索引代替了键的待办事项名称,这样可以正常工作,并且允许用户多次添加相同的项目,并且在删除时,它只会删除该特定项目,而不是所有具有相同名称的项目,但是使用索引作为键不是一个好主意。