问题描述
我正在开发一个简单的Todo App,目前还无法更新App.js组件的状态。
这是我的App.js:
import React,{ Component } from "react";
import TodoItem from "./TodoItem";
import todosData from "./TodoData";
class App extends Component {
constructor() {
super();
this.state = {
loadedData: todosData,};
}
newChange = (id) => {
const update = this.state.loadedData.map((todo) => {
if (todo.id === id) {
todo.completed = !todo.completed;
}
return todo;
});
// this is where my update variable will not update?
console.log(update);
this.setState({ loadedData: update });
};
render() {
const todoComponent = this.state.loadedData.map((item) => (
<TodoItem
key={item.id}
text={item.text}
completed={item.completed}
newChange={this.newChange}
/>
));
return <div className="todo-list">{todoComponent}</div>;
}
}
export default App;
这是我的TodoItem Componenet(我猜想,一旦正确传递此状态,它将正常工作):
import React from "react";
class TodoItem extends React.Component {
render() {
return (
<div className="todo-item">
<input
type="checkBox"
checked={this.props.completed}
onChange={() => this.props.newChange(this.props.id)}
/>
<p>{this.props.text}</p>
</div>
);
}
}
export default TodoItem;
最后,我的数据只是由对象组成的数组:
const todosData = [
{
id: 1,text: "Take out the trash",completed: true
},{
id: 2,text: "Grocery shopping",completed: false
},{
id: 3,text: "Clean gecko tank",{
id: 4,text: "Mow lawn",{
id: 5,text: "Catch up on Arrested Development",completed: false
}
]
export default todosData
我最大的问题是为什么当我通过newChange()方法进行映射时,我的 update 变量不会更新吗?
当我进行console.log记录时,它会显示完全相同的数据,而我想要的属性不会得到更新?
loadedData仍然与更新完全相同。
解决方法
丹尼,您在正确的位置放console.log(update)
。这样,您发现该函数实际上并未更新map函数中的现有状态。
要找出原因,您需要检查map函数内部发生的情况,第一步是测试您在其中使用的所有内容。在这种情况下,您使用的是this.props.id
,则可以通过将console.log放入其值来进行检查:
newChange = id => {
console.log("id:",id); // NEW
const update = this.state.loadedData.map(todo => {
if (todo.id === id) {
todo.completed = !todo.completed;
}
return todo;
});
// this is where my update variable will not update?
console.log(update);
this.setState({ loadedData: update });
};
好吧,在这种情况下,当您尝试单击待办事项时,它将打印id: undefined
,因为您实际上没有将其作为道具传递。 map函数在待办事项之间循环,但从未找到任何满足if (todo.id === id)
的待办事项(因为在您的情况下它会转换为if (todo.id === undefined)
)
修复很简单,只需将id
作为道具传递给todoComponent
const todoComponent = this.state.loadedData.map(item => (
<TodoItem
id={item.id} // NEW
key={item.id}
text={item.text}
completed={item.completed}
newChange={this.newChange}
/>
));
,
执行以下操作时,您不小心在function findInJson(objJsonResp,key,value,aType){
if(aType=="edit"){
return objJsonResp.find(x=> x[key] == value);
}else{//delete
var a =objJsonResp.find(x=> x[key] == value);
objJsonResp.splice(objJsonResp.indexOf(a),1);
}
}
处理程序中改变了状态:
newChange
相反,创建一个全新的todo.completed = !todo.completed;
对象切片:
state
或者,如果您不能使用扩展运算符(newChange = (id) => {
this.setState({
loadedData: this.state.loadedData.map((todo) => ({
...todo,completed: todo.id === id ? !todo.completed : todo.completed,})),});
};
),请尝试以下操作:
...
您可以在React官方文档的“ The Power Of Not Mutating Data”下阅读更多内容
,在App.js中创建ToDoItems时,您只是缺少一个道具(id)
您尝试在ToDoItem中访问它,但是您从未设置它...
因此您在App中的渲染功能应如下所示:
render() {
const todoComponent = this.state.loadedData.map((item) => (
<TodoItem
key={item.id}
id={item.id}
text={item.text}
completed={item.completed}
newChange={this.newChange}
/>
));
return <div className="todo-list">{todoComponent}</div>;
}