我正在为基本的待办事项列表应用程序创建删除功能;但是,尝试从列表中删除某个项目并再次设置状态时遇到了问题。它不断给我一个this.setState is not a function
错误。问题出在deleteTodo(id)
中。
我的TodoStore.js
import { EventEmitter } from "events";
import dispatcher from "../dispatcher";
import * as TodoActions from "../actions/TodoActions";
class TodoStore extends EventEmitter {
constructor() {
super()
this.deleteTodo = this.deleteTodo.bind(this)
this.state = { todos: [
{
id: 113464613,
text: "Go Shopping"
},
{
id: 235684679,
text: "Pay Water Bill"
},
]};
}
createTodo(text) {
const id = Date.now();
this.state.todos.push({
id,
text,
});
this.emit("change");
}
deleteTodo(id) {
const todos = this.state.todos.filter(todo => id !== todo.id)
console.log(todos)
this.setState({
todos: todos
})
this.emit("change")
}
getAll() {
return this.state.todos;
}
handleActions(action) {
switch(action.type) {
case "CREATE_TODO": {
this.createTodo(action.text);
break;
}
case "DELETE_TODO": {
this.deleteTodo(action.id);
break;
}
}
}
}
const todoStore = new TodoStore;
dispatcher.register(todoStore.handleActions.bind(todoStore));
window.dispatcher = dispatcher
export default todoStore;
控制台中的错误消息:
TodoStore.js:46 Uncaught TypeError: _this.setState is not a function
at TodoStore._this.deleteTodo (TodoStore.js:46)
at TodoStore._this.handleActions (TodoStore.js:63)
at Dispatcher._invokeCallback (Dispatcher.js:198)
at Dispatcher.dispatch (Dispatcher.js:174)
at Object.deleteTodo [as b] (TodoActions.js:11)
at Todos.deleteTodo (Todos.js:34)
at onClick (Todos.js:51)
at HTMLUnknownElement.callCallback (react-dom.development.js:145)
at Object.invokeGuardedCallbackDev (react-dom.development.js:195)
at invokeGuardedCallback (react-dom.development.js:248)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:262)
at executeDispatch (react-dom.development.js:593)
at executeDispatchesInOrder (react-dom.development.js:615)
at executeDispatchesAndRelease (react-dom.development.js:713)
at executeDispatchesAndReleaseTopLevel (react-dom.development.js:724)
at forEachAccumulated (react-dom.development.js:694)
at runEventsInBatch (react-dom.development.js:855)
at runExtractedEventsInBatch (react-dom.development.js:864)
at handleTopLevel (react-dom.development.js:4857)
at batchedUpdates$1 (react-dom.development.js:17498)
at batchedUpdates (react-dom.development.js:2189)
at dispatchEvent (react-dom.development.js:4936)
at interactiveUpdates$1 (react-dom.development.js:17553)
at interactiveUpdates (react-dom.development.js:2208)
at dispatchInteractiveEvent (react-dom.development.js:4913)
答案 0 :(得分:2)
首先,我将类声明为React组件,否则,您将无法拥有“状态”,也将无法访问setState函数(这是创建新状态的函数) )。
然后,我不会绑定这些函数,只是在您要在类中声明的每个函数中,我都将按照以下方式(在代码中指明您的方式)进行绑定:
nameOfFunction = () =>
使用这种形式(arrow function),您可以获得范围,因此可以使用它来访问状态。
最后,当您按下添加新元素时,这在React中被禁止。状态是不可变的,您只能创建一个新状态来进行任何更改,因此我们使用setState并帮助自己完成... this.state.todos(spread operator)。
它通过创建一个新数组并添加带有id和text的所需对象来实现。
希望我能对您有所帮助。 最好,
class TodoStore extends React.Component {
constructor(props) {
super(props);
this.state = {
todos: [
{
id: 113464613,
text: "Go Shopping",
},
{
id: 235684679,
text: "Pay Water Bill",
},
],
};
}
createTodo = text => {
const id = Date.now();
this.setState({
todos: [...this.state.todos, { id, text }],
});
this.emit("change");
};
deleteTodo = id => {
const todos = this.state.todos.filter(todo => id !== todo.id);
console.log(todos);
this.setState({
todos,
});
this.emit("change");
};
getAll = () => this.state.todos;
handleActions = action => {
switch (action.type) {
case "CREATE_TODO": {
this.createTodo(action.text);
break;
}
case "DELETE_TODO": {
this.deleteTodo(action.id);
break;
}
}
};
}
答案 1 :(得分:0)
出现此错误的原因是,您无法在类方法中访问该类的this对象。要解决此问题,请在要使用set state的构造函数中使用bind(this)
。
constructor(){
super();
this.state={};
this.createTodo=this.createTodo.bind(this);
this.deleteTodo=this.deleteTodo.bind(this);
this.getAll=this.getAll.bind(this);
this.handleActions=this.handleActions.bind(this);
}
您还可以使用箭头功能在函数内部使用此功能。 例如
createTodo = (text) => {
}
答案 2 :(得分:0)
EventEmitter 类没有 this.setState 函数。如果要使用它,则必须位于React.Component中。
在这种情况下。我认为您可以在听发射-> 更改
时 setState答案 3 :(得分:0)
如果该类未从React扩展Component,则不能使用setState
。但是,您实际上并不需要setState,因为您所做的实际上只是“服务”而不是React组件。
您可以只使用自己的内部“状态”变量,可以将其称为todos
,因为它仅包含待办事项列表。对于设置它,您不应该对其进行突变,而应从旧对象创建一个新对象并将其与新值合并:
this.todos = [ ...this.todos, { id, text } ]
或者您可以使用concat
:
this.todos = this.todos.concat({ id, text })
要删除的内容相同,只需使用过滤器即可。