在地图函数中与布尔值相反的setState反应不更改状态

时间:2020-08-27 08:44:21

标签: reactjs setstate

我在ReactJS中创建了一个简单的待办事项列表。它将加载存储在文件“ TodoData.js ”中的待办事项组件,数据按如下方式存储在该文件中:

const todosData = [
    {
        id:1,
        text: "Take out the thrash",
        completed: true
    },
    {
        id:2,
        text: "Grocery shopping",
        completed: false
    },

App.js使用TodoItem.js组件通过 map 函数呈现每个待办事项。 TodoItem.js使用条件渲染:

   if (props.item.completed == true) {
        return (
        <div className="todoclassDone">
            <input type="checkbox" 
            onChange={ () => props.handleChange(props.item.id)}/>
            <p className="lalatext"><del>{props.item.text}</del></p>
        </div>   
        )
    }
    else { .... //same code as above but with other className.

在App.js中,我使用TodoItem.js组件使用地图函数在TodoData中渲染每个项目;如果data.completed = true,背景为绿色,否则背景为红色。

问题:但是,App.js中的 handleChange(id)函数无法正常工作。我遍历了todosData中的所有对象;如果该ID与用户单击的复选框的ID相似,则应使用 todo.completed =!todo.completed 更改为相反的布尔值。但是,在运行此代码时,没有任何反应。 handleChange函数:

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

其他信息:上面提到的问题特别奇怪,因为如果我将用户单击的复选框的布尔值更改为false或true,它将起作用。这不会导致所需的行为,因为现在我只能将todo.completed从false更改为true。 ;在这种情况下, handleChange 函数将如下所示:

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

我们非常感谢您的帮助,在此先感谢您! :-)

2 个答案:

答案 0 :(得分:1)

Ciao,您可以尝试复制阵列上的状态,修改阵列并设置状态(更新后的阵列)。像这样:

handleChange(id) {
    let result = this.state.todos;
    result = result.map(todo => {
        if (todo.id === id) todo.completed = !todo.completed;
        return todo;
    })
    this.setState({todos: result})
}

答案 1 :(得分:0)

您应该在setState回调中返回带有新状态对象的新状态。

带有相关代码的示例待办事项组件

class Todo extends Component {
  state = {
    todos: todosData,
  }

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

        return todo;
      });

      return { todos };

  }
}