反应setState不更新状态

时间:2020-09-01 21:26:01

标签: javascript reactjs setstate

我是React的新手,使用setState方法更改状态时遇到了一些麻烦。单击复选框时,我试图更新待办事项的状态。当我调试handleChange方法时,它会暂时更改项目的状态。不幸的是,最终状态就像开始时一样(复选框的状态从不更改)。有人知道问题出在哪里吗?

class App extends React.Component {
constructor() {
    super()
    this.state = {
        todos: todosData,
    }
    this.handleChange = this.handleChange.bind(this)
  }


handleChange(id){
    this.setState(prevState => {
        const updatedTodos = prevState.todos.map(todo => {
             if (todo.id === id) {
                  todo.completed = !todo.completed
             }
             return todo
        })
        return {
            todos: updatedTodos
        }
      })
    }


render()  {
    const todoItems = this.state.todos.map(item => <ToDoItem key={item.id} todoItem={item} 
    handleChange={this.handleChange}/>) 

  return (
       <div className="App">
         {todoItems}
       </div>
   );
}

}

export default App;

这是我的ToDoItem组件:

import React from 'react'

function ToDoItem(props){
    return (
        <div className = "todo-list">
            <div className = "todo-item">
                <input type="checkbox" 
                    checked={props.todoItem.completed} 
                    onChange = {() => props.handleChange(props.todoItem.id)}/>
                <p>{props.todoItem.text}</p>
            </div>
        </div>
    )
}

export default ToDoItem

2 个答案:

答案 0 :(得分:1)

只需使用此处理程序,让我知道它是否有效。

handleChange(id){
    const list = this.state.todos.slice();
    const index = list.findIndex(o => o.id === id);
    list[index].completed = !list[index].completed;
    this.setState({ todos: list });
}

答案 1 :(得分:0)

我认为问题出在这里

   handleChange(id){
     this.setState(prevState => {
        const updatedTodos = prevState.todos.map(todo => {
           if (todo.id === id) {
               todo.completed = !todo.completed
           }
           return { ...todo }; // need to return a new object
        })
        return {
            todos: updatedTodos
        }
      })
    }

todo是对象和事件,如果每次都将todos设置为新对象,则其项引用相同的对象,并且ToDoItem使用它。