javascript - 通过映射函数 react 更改记录属性无法正常工作

标签 javascript reactjs

我的 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
      }) 

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.

参见Object references and copying

关于javascript - 通过映射函数 react 更改记录属性无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68239825/

相关文章:

javascript - 单击启用 Highcharts 导出

javascript - 将鼠标悬停在菜单项上 React

javascript - 如何将react js组件拆分成多个文件

javascript - 如何在 React 中从另一个组件重新渲染一个组件

javascript - 如何在 React 应用程序的页面上的任何位置检测 keydown?

javascript - 在组件内部定义自定义 Hook 有什么问题吗?

javascript - Meteor递归方法调用导致无限循环

javascript - 奇怪的 ISO 格式日期字符串到 Javascript 日期

javascript - 固定位置在 IE 10 与 Bootstrap Modal 中的 Chrome 和 Firefox 中表现不同

javascript - 打印出变量中包含的数学表达式