React 是否在内部创建 prevState 的深副本或浅副本?

Glo*_*gov 4 state immutability setstate reactjs

我刚刚开始编程,最近用 React 编写了我的第一个应用程序,虽然它确实有效,但我不确定我是否正确处理我的内部状态。我的问题是 setState 方法是否创建“prevState”的不可变深层副本或不一定?举个例子:

 menuAddRecHandler = () => {
    this.setState((prevState) => {
      const updatedState = {...prevState};
      const dayInd = updatedState.menu.recipes.findIndex(item => item.dayNum === updatedState.menuInternal.currentDay);
      updatedState.menu.recipes[dayInd].recList.push({
        name: prevState.menuInternal.menuRecSelect,
        portions: prevState.menuInternal.menuNumPortInput
      });
      return updatedState;
    })
  }
Run Code Online (Sandbox Code Playgroud)

在我的处理程序中,我将一个对象推送到 UpdatedState 对象的嵌套数组中,该对象是由扩展运算符从 prevState 复制过来的。现在我知道展开运算符仅生成浅表副本,但是 setState 方法内部提供的 prevState 也是浅表副本吗?这是否意味着我实际上是通过调用此处理程序直接改变我的状态?如果是这样,我该如何解决这个问题?谢谢。

Agn*_*ney 5

来自文档

第一个参数是具有签名的更新程序函数:

(state, props) => stateChange

state 是应用更改时组件状态的引用。不应该直接突变。相反,应该通过基于状态和道具的输入构建新对象来表示更改。

如何在不变异的情况下达到相同的结果?

menuAddRecHandler = () => {
  this.setState((prevState) => {
    return {
      ...prevState,
      menu: {
        ...prevState.menu,
        recipes: prevState.menu.recipes.map((item) => {
          if(item.dayNum === prevState.menuInternal.currentDay) {
            return {
              ...item,
              recList: [
                ...item.recList,
                {
                  name: prevState.menuInternal.menuRecSelect,
                  portions: prevState.menuInternal.menuNumPortInput
                }
              ]
            }
          }
          return item;
        })
      }
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

这显然很容易出错,其想法是减少更深的状态。Redux 的文档提供了一些规范化状态的技巧

您还可以查看不可变状态库,例如ImmutableJSImmer