在没有我调用 setState 的情况下反应状态更新?

Eva*_*nss 0 reactjs

我正在使用 React 制作一个待办事项列表应用程序。我的状态有项目,也有删除的项目,以便它们可以恢复:

  state = {
    items: ['item 1', 'item 2', 'item 3'],
    deletedItems: ['item 4', 'item 5']
  };
Run Code Online (Sandbox Code Playgroud)

因此,我删除项目的功能必须从项目状态中删除项目并将其放入删除的项目状态。

 removeItem(number) {
    const itemsState = this.state.items;
    const deletedItemsState = this.state.deletedItems;

    const itemToBeDeleted = itemsState[number];
    deletedItemsState.push(itemToBeDeleted);

    itemsState.splice(number, 1);
    this.setState({ items: itemsState });
  }
Run Code Online (Sandbox Code Playgroud)

上面的代码有效,但我很困惑为什么我没有调用 setState 就更新了 DeletedItems 状态。我在这里没有遵循最佳实践吗?

Chr*_*ris 5

我在这里没有遵循最佳实践吗?

不。问题是您没有使用临时变量,就像您可能相信的那样,而是deletedItems直接变异。基本上:

const itemsState = this.state.items;
const deletedItemsState = this.state.deletedItems;
Run Code Online (Sandbox Code Playgroud)

这些行不会创建相应状态变量的副本,而只会创建对它们的引用。

所以当你做

deletedItemsState.push(itemToBeDeleted);
Run Code Online (Sandbox Code Playgroud)

你是直接改变状态!您可能已经知道,这是一个禁忌。

为什么会发生这种情况?

要理解这一点,您必须了解原始值和复合值之间的分配工作方式不同。

例如:

var x = y;
Run Code Online (Sandbox Code Playgroud)

x将复制yif的值y是字符串、数字、布尔值、空值或未定义。但是,如果它是一个对象,数组或函数x将存储其引用。


解决方案:

您需要做的是创建它们的浅表副本。像这样:

const itemsState = this.state.items.slice();
const deletedItemsState = this.state.deletedItems.slice();
Run Code Online (Sandbox Code Playgroud)

这将使itemsState并且deletedItemsState从不同的变量this.state.itemthis.state.deletedItems分别。


演示:

const itemsState = this.state.items;
const deletedItemsState = this.state.deletedItems;
Run Code Online (Sandbox Code Playgroud)
deletedItemsState.push(itemToBeDeleted);
Run Code Online (Sandbox Code Playgroud)