响应中的可变状态更新

时间:2020-06-01 12:15:34

标签: javascript arrays reactjs react-state-management

例如,我们有一个这样定义的状态,其中包含一些待办事项,如果要完成,我们想更改该待办事项的完成情况

[0]

为此,我们可以取消此操作。

this.state = {
  // store an array of todo objects
  todos: [
    { task: 'do the dishes', done: false, id: 1 },
    { task: 'vacuum the floor', done: true, id: 2 }
  ]
};

}

但是我有点困惑,数组上的find方法将向我们返回与其内部条件匹配的元素,然后将其存储在另一个变量中,然后进行访问以将其更改为true。 但是,我们仍然没有更改原始状态值,因为这是一个副本。

那我们怎么可以用它来保存它呢?

  const theTodo = this.state.todos.find(t => t.id === id);
  theTodo.done = true; // NOOOOO

  this.setState({
    todos: this.state.todos
  });

3 个答案:

答案 0 :(得分:2)

代码起作用的原因是因为State Updates are Merged

调用setState()时, React将您提供的对象合并到当前状态

但是,这只是不好的做法 You shouldn't mutate this.state directly

切勿直接突变this.state,因为事后致电setState()可能会取代您所做的突变。将this.state视为不变。

为完整起见,只需pass a functionthis.setState并使用map保存不可变性规则。

通过更新功能可让您访问更新程序中的当前状态值。

this.setState((prevState) => {
  const todos = prevState.todos.map((todo) =>
    todo.id === id ? { ...todo, done: true } : todo
  );
  return { todos };
});

答案 1 :(得分:0)

只需spread一切


this.setState(oldState => {
  const todos = oldState.todos;
  const todoIndex = todos.findIndex(pr => pr.id === id);
  const todo = todos[todoIndex];
  const newTodos = [...todos.slice(0, todoIndex), {...todo, done: true}, ...todos.slice(todoIndex + 1)]

  return {
    ...oldState,
    todos
  }
});

答案 2 :(得分:-1)

这不是问题,也不是与React框架有关的东西。这是对JavaScript的基本理解。当然,您将获得一个匹配项,find方法适用于任何数组,而您的 todo 是一个数组。 find方法返回一个新对象,而不是对其的引用。如果只想更新,请创建待办事项的副本,然后使用任何方法更新正确的待办事项,然后将复制的待办事项添加到新状态。您可以使用沉浸式运算符,也可以使用扩散运算符,可以通过多种方法进行。