我的 react 应用程序中有一个有线行为。一旦我检查了我想要通过循环的 onChange
方法(由父 App
组件处理)更新复选框的项目,我就尝试创建一个简单的待办事项列表浏览上一个任务列表并更改具有所选 ID 的任务。一旦我执行task.completed = !task.completed
。我得到这个有线结果:
完成是真然后是假?!!!我无法弄清楚这可能是什么。
{id: 2, text: "Wash my teeth", completed: true}
completed: false
id: 2
text: "Wash my teeth"
__proto__: Object
这是我的 TodoItem 组件:
function TodoItem({task, handleChange}){
return(
<div className="todo-item">
<input type="checkbox"
onChange={() => handleChange(task.id)}
checked={task.completed}
/>
<p>{task.text}</p>
</div>
)
}
export default TodoItem;
这是我的应用程序组件:
class App extends React.Component {
constructor(){
super()
this.state = {
todos: tasks
}
}
handleChange = (id) => {
this.setState(prevState => {
const updatedTodos = prevState.todos.map(task => {
if (task.id === id){
task.completed = !task.completed
console.log(task)
}
return task
})
return {
todos: updatedTodos
}
})
}
render(){
console.log('render')
const todoItems = this.state.todos.map(item => {
return (
<TodoItem
key={item.id}
task = {item}
handleChange={this.handleChange}
/>)
});
return (
<div className="todo-list">
{todoItems}
</div>
);
}
}
最佳答案
在 JavaScript 中,对象是通过引用而不是值传递的,因此,如果您直接改变映射函数内的属性,它将在原始数组 prevState.todos
中更改它。 。因此,您需要使用属性的新值创建对象的新副本。
const updatedTodos = prevState.todos.map(task => {
let newTask = {...task}
if (task.id === id){
newTask.completed = !task.completed
}
return newTask
})
或
const updatedTodos = prevState.todos.map(task => {
if (task.id === id){
return {...task, completed: !task.completed};
}
return task
})
block 引用>Objects are assigned and copied by reference. In other words, a variable stores not the “object value”, but a “reference” (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object itself.
关于javascript - 通过映射函数 react 更改记录属性无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68239825/