【问题标题】:good way to change React JS state改变 React JS 状态的好方法
【发布时间】:2021-08-28 12:01:27
【问题描述】:
{
 "user":{
  "auth":true,
  "sub_sq":[
   "1":{
    "createdAt":"2021-08-28"
   }
  ]
 },
 "sub":{
  "name":"123"
  "sub_sq":[
   "1":{
    "createdAt":"2021-08-21"
   }
  ]
 }
}

你好 当像上面那样改变状态对象时

对用户对象应用更改时

  1. 深度复制后是否需要更改整个对象?

  2. 还是只在 deepcopy 后将更改应用到用户对象?

我喜欢 two(2) 方法,所以我应用第一个(仅深拷贝更改的对象)

但我不确定这是否是正确的做法,所以我正在寻求建议。

谢谢

【问题讨论】:

  • 考虑使用扩展运算符
  • 当您想更改嵌套对象中的某些内容时,您需要创建父对象和要更改的对象的新副本。例如,如果您想更改用户对象内部的某些内容,您需要制作entire state 的副本和user 对象的新副本。它不需要在这里创建sub 的副本,因为其中没有任何更改。
  • 嵌套越多,更新状态就越困难,因为您需要复制所有嵌套级别。您可以使用像 immer - immerjs.github.io/immer 这样的库。

标签: reactjs deep-copy


【解决方案1】:

简而言之,您应该只在新状态值中复制您未更改的内容。例如:

const newState = {
  ...oldState,
  user: {
    ...oldState.user,
    auth: false,
  }
}

更一般地说,将深度嵌套的状态对象拆分为多个状态被认为是一种更好的做法。这使您可以更具体地了解您的状态更新以及稍后的状态监听器(即useEffect)。例如,您可以将原始状态值拆分为两个变量:

const [user, setUser] = useState({
  "auth": true,
  "sub_sq": [
    "1": {
      "createdAt":"2021-08-28"
    }
  ]
});
const [sub, setSub] = useState({
  "name": "123"
  "sub_sq": [
    "1": {
      "createdAt":"2021-08-21"
    }
  ]
});

如果你坚持使用复合状态,最好使用 reducer 以更可控的方式更新每个状态“部分”。来自React's useReducer documentation

当你有涉及多个子值的复杂状态逻辑或当下一个状态依赖于前一个时,useReducer 通常比 useState 更可取

【讨论】:

  • 我刚刚回答了谢谢!!
【解决方案2】:

这确实是状态管理的一个棘手问题。使用扩展运算符或建议的immer library 是一个不错的选择。我自己为此创建了@rimbu/deep library。它有一个名为patch 的方法,允许您编写如下内容:

import { patch } from '@rimbu/deep';

const person = {
  name: "Alice",
  age: 34,
  address: {
    street: "Random street",
    number: 45
  },
  friends: ["Bob", "Carol"]
};

const updatedPerson = patch(person)({
  age: v => v + 1,
  address: {
    street: "Other street"
  },
  friends: v => [...v, "Anne"]
})

// updatedPerson is now:
// {
//   name: "Alice",
//   age: 35,
//   address: {
//     street: "Other street",
//     number: 45
//   },
//   friends: ["Bob", "Carol", "Anne"]
// }

它很新,需要更多文档,但只是想分享。

你可以玩这个 CodeSandbox:

【讨论】:

    猜你喜欢
    • 2014-07-20
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 2023-03-29
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多