正在学习ReactJS并构建我的todo应用程序。 但是,当我尝试删除任务时遇到问题。
我有两个文件TodoList.js和TodoItems.js
TodoList.js
import React, {Component} from 'react';
import TodoItems from './TodoItems';
class TodoList extends Component {
//Function to handle adding tasks
addTask(event) {
//Get task Value
let task = this.refs.name.value;
//Newitem Object
if (task !== "") {
let newItem = {
text: task,
key: Date.now()
}
this.setState({
items: this.state.items.concat(newItem)
});
this.refs.name.value = ""; //Blank out the task input box
}
}
deleteItem(key) {
var filteredItems = this.state.items.filter(function (item) {
return (item.key !== key);
});
this.setState({
items: filteredItems
});
}
constructor(props) {
super(props);
this.state = {
items: []
};
this.addTask = this.addTask.bind(this);
this.deleteItem = this.deleteItem.bind(this);
}
render() {
return (
<div className="todoListMain">
<div className="header">
<form>
<input placeholder="Enter Task" id="name" ref="name"></input>
<button type="button" onClick={this.addTask}>Add Task</button>
</form>
</div>
<div className="list">
<TodoItems entries={this.state.items} delete={this.deleteItem} />
</div>
</div>
);
}
}
export default TodoList;
TodoItems.js具有以下代码
import React, {Component} from 'react';
class TodoItems extends Component {
constructor(props) {
super(props);
this.state = {};
}
delete(key) {
this.props.delete(key);
}
listTasks(item) {
return <li key={item.key} onClick={() => this.delete(item.key)}>{item.text}</li>
}
render() {
let entries = this.props.entries;
let listItems = entries.map(this.listTasks);
return (
<ul className="theList">
{listItems}
</ul>
);
}
}
export default TodoItems;
点击任务时,我在删除任务时遇到错误。
我得到的错误是here
我猜这意味着未定义函数delete,但是已经定义了它,但仍然出现错误。 谁能解释我如何解决此问题?
答案 0 :(得分:1)
您永远不要尝试直接修改道具,如果组件中的某些因素影响了其渲染方式,请将其置于您的状态:
this.state = {
entries: props.entries
};
要删除您的元素,只需将其从entries
数组中过滤出来:
delete(key) {
this.setState(prevState => ({
entries: prevState.entries.filter(item => item.key !== key)
}))
}
现在是渲染功能:
render() {
const { entries } = this.state //Takes the entries out of your state
return (
<ul className="theList">
{entries.map(item => <li key={item.key} onClick={this.delete(item.key)}>{item.text}</li>)}
</ul>
);
}
完整代码:
class TodoItems extends Component {
constructor(props) {
super(props);
this.state = {
entries: props.entries
};
}
delete = key => ev => {
this.setState(prevState => ({
entries: prevState.entries.filter(item => item.key !== key)
}))
}
render() {
const { entries } = this.state
return (
<ul className="theList">
{entries.map(item => <li key={item.key} onClick={this.delete(item.key)}>{item.text}</li>)}
</ul>
);
}
}
您还应该尝试永远不要使用var
。如果您不打算修改变量,请使用const
,否则请使用let
。
EDIT:编辑中显示的错误来自listTasks
未被绑定到您的班级。要解决它,您可以将其绑定(如下面的其他答案所示)或在另一个函数中进行转换:
listTasks = item => {
return <li key={item.key} onClick={() => this.delete(item.key)}>{item.text}</li>
}
短语法:
listTasks = ({ key, text }) => <li key={key} onClick={() => this.delete(key)}>{text}</li>
答案 1 :(得分:0)
欢迎来到Stackoverflow!
检查React Docs的this section。您必须将类函数绑定到构造函数中,或者使用箭头函数。
class TodoItems extends Component {
constructor(props) {
// ...
this.delete = this.delete.bind(this);
}
delete(key) {
this.props.delete(key);
}
// Or without binding explicitly:
delete2 = (key) => {
// ...
}
}
答案 2 :(得分:0)
替换此:
onClick={this.delete(item.key)}
// passes the result of `this.delete(item.key)` as the callback
通过这个:
onClick={() => this.delete(item.key)}
// triggers `this.delete(item.key)` upon click