我正在研究todo应用程序,以了解反应的力量。我创建了3个组件,我将在下面向您展示。所以我想从一个位于另一个组件中的数组状态中删除一个待办事项。
查看下面的组件。
这是我的TodoAppComponent:
import AddTodoComponent from '../AddTodoComponent/AddTodoComponent';
class TodoAppComponent extends Component {
render() {
return (
<div id="page-content-wrapper">
<div className="container">
<div className="row">
<div className="col-lg-6 col-lg-offset-3">
<h1 className="m-b-md">What needs to be done?</h1>
<AddTodoComponent></AddTodoComponent>
</div>
</div>
</div>
</div>
);
}
}
export default TodoAppComponent;
这里我有TodoItemComponent:
class TodoItemComponent extends Component {
deleteTodo(todo){
console.log('deleteTodo', todo);
this.props.onDelete(this.props.todo);
}
render() {
console.log('this.props.todo', this.props.todo);
return (
<div>
<li className="list-group-item todo-item">
<button className="btn btn-xs btn-react btn-circle m-r-md">
<span className="fa fa-check"></span>
</button>
{this.props.todo}
<span className="pull-right">
<button className="btn btn-xs btn-react btn-circle m-r-xs">
<span className="fa fa-pencil-square-o"></span>
</button>
<button className="btn btn-xs btn-react btn-circle" onClick={this.deleteTodo.bind(this.props.todo)}>
<span className="fa fa-trash-o"></span>
</button>
</span>
</li>
</div>
);
} }
导出默认TodoItemComponent
;
class TodoItemComponent extends Component {
deleteTodo(){
// this.setState({
// data: update(this.state.data, {$splice: [[index, 1]]})
// })
console.log('deleteTodo', this.props.todo);
}
render() {
console.log(this.props.todo, this.props.title);
return (
<div>
<li className="list-group-item todo-item">
<button className="btn btn-xs btn-react btn-circle m-r-md">
<span className="fa fa-check"></span>
</button>
{this.props.todo}
<span className="pull-right">
<button className="btn btn-xs btn-react btn-circle m-r-xs">
<span className="fa fa-pencil-square-o"></span>
</button>
<button className="btn btn-xs btn-react btn-circle" onClick={this.deleteTodo}>
<span className="fa fa-trash-o"></span>
</button>
</span>
</li>
</div>
);
}
}
export default TodoItemComponent;
这是AddTodoComponent:
import TodoItemComponent from '../TodoItemComponent/TodoItemComponent';
class AddTodoComponent extends Component {
constructor(props) {
super(props);
this.state = {
todo: '',
todoArray: []
};
}
addTodo(e){
this.setState({ todo: e.target.value });
this.state.todoArray.push(<TodoItemComponent todo={this.state.todo} onDelete={this.delete}></TodoItemComponent>);
}
delete(index){
// this.setState({
// todoArray: update(this.state.todoArray, {$splice: [[index, 1]]})
// });
console.log('testDelete', this.state.todoArray);
}
handleChange(e){
this.setState({ todo: e.target.value });
}
render() {
return (
<div>
<div className="input-group m-b-md">
<input type="text" className="form-control add-todo" placeholder="Todo..." value={this.state.todo} onChange={this.handleChange.bind(this)} />
<span className="input-group-btn">
<button className="btn btn-react" type="button" onClick={this.addTodo.bind(this)}>Add</button>
</span>
</div>
<ul className="list-group">
{this.state.todoArray}
</ul>
</div>
);
}
}
export default AddTodoComponent;
如您所见,我在单击删除按钮时尝试记录this.props.todo
,因此当它在TodoItemComponent中发出deleteTodo function
时。它返回Uncaught TypeError: Cannot read property 'props' of null
的位置,但在render()
方法中,它会被识别并记录输入的结果。
因此,我尝试在TodoItemComponent
:
<button className="btn btn-xs btn-react btn-circle" onClick={this.deleteTodo.bind(this.props.todo)}>
<span className="fa fa-trash-o"></span>
</button>
所以函数看起来像这样:
deleteTodo(todo){
console.log('deleteTodo', todo);
this.props.onDelete(this.props.todo);
}
有人可以帮我解决这个问题吗?
答案 0 :(得分:2)
您的问题是此处误导Function.prototype.bind
:
onClick={this.deleteTodo.bind(this.props.todo)}
// ^ you're binding todo as the context
第一个参数应该是绑定函数的上下文,即this
,而不是待办事项。
onClick={this.deleteTodo.bind(this)}
您应该在this.props.todo
函数中使用deleteTodo
(现在具有适当的上下文)。
或者,您可以an arrow function(维护其外部背景)传递todo
:
onClick={() => this.deleteTodo(this.props.todo)}
并且您的deleteTodo
方法会收到todo
作为其第一个参数。
答案 1 :(得分:1)
将数据存储在this.state
中,并仅在render
中创建React元素,如下所示:
class AddTodoComponent extends Component {
constructor(props) {
super(props);
this.state = {
todo: '',
todoArray: []
};
}
addTodo(e){
this.state.todoArray.push(e.target.value);
this.setState({ todo: '' });
}
delete(index){
console.log('testDelete', this.state.todoArray);
}
handleChange(e){
this.setState({ todo: e.target.value });
}
render() {
return (
<div>
<div className="input-group m-b-md">
<input type="text" className="form-control add-todo" placeholder="Todo..." value={this.state.todo} onChange={this.handleChange.bind(this)} />
<span className="input-group-btn">
<button className="btn btn-react" type="button" onClick={this.addTodo.bind(this)}>Add</button>
</span>
</div>
<ul className="list-group">
{this.state.todoArray.map((todo, index) => (
<TodoItemComponent todo={todo} onDelete={this.delete.bind(this, index)}></TodoItemComponent>
))}
</ul>
</div>
);
}
}