无法在使用 React 的 ToDo 应用程序中使用 ES6 映射状态?
Cannot map through state using ES6 in a ToDo App using React?
我正在开发一个简单的 ToDo 应用程序,目前我一直在更新我的 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",
completed: false
},
{
id: 4,
text: "Mow lawn",
completed: true
},
{
id: 5,
text: "Catch up on Arrested Development",
completed: false
}
]
export default todosData
我最大的问题是为什么我的 newChange() 方法中的 update 变量在我映射时没有更新?
当我 console.log 它显示完全相同的数据时,我想要的 属性 没有得到更新?
loadedData 仍然与 update 完全相同。
当您执行以下操作时,您不小心改变了 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,
})),
});
};
或者,如果您不能使用扩展运算符 (...
),请尝试以下操作:
newChange = (id) => {
this.setState({
loadedData: this.state.loadedData.map((todo) =>
Object.assign({}, todo, {
completed: todo.id === id ? !todo.completed : todo.completed,
})
),
});
};
您可以在“The Power Of Not Mutating Data”下的官方 React 文档中阅读更多信息
您在 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>;
}
丹尼,你把 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
作为 prop 传递给 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}
/>
));
我正在开发一个简单的 ToDo 应用程序,目前我一直在更新我的 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",
completed: false
},
{
id: 4,
text: "Mow lawn",
completed: true
},
{
id: 5,
text: "Catch up on Arrested Development",
completed: false
}
]
export default todosData
我最大的问题是为什么我的 newChange() 方法中的 update 变量在我映射时没有更新?
当我 console.log 它显示完全相同的数据时,我想要的 属性 没有得到更新?
loadedData 仍然与 update 完全相同。
当您执行以下操作时,您不小心改变了 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,
})),
});
};
或者,如果您不能使用扩展运算符 (...
),请尝试以下操作:
newChange = (id) => {
this.setState({
loadedData: this.state.loadedData.map((todo) =>
Object.assign({}, todo, {
completed: todo.id === id ? !todo.completed : todo.completed,
})
),
});
};
您可以在“The Power Of Not Mutating Data”下的官方 React 文档中阅读更多信息
您在 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>;
}
丹尼,你把 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
作为 prop 传递给 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}
/>
));