首页 > 解决方案 > 有没有更简单的方法在 React 中设置状态?

问题描述

我只是 React 的初学者,我一直在寻找一种更简单的方法来设置状态。一个重要的注意事项是它位于功能组件内部。

    const [ personState, setPersonsState ] = useState({
      persons: [
        { name : 'Max', age : 28 },
        { name : 'Manu', age : 29 },
        { name : 'Stephanie', age : 26 }
      ]
    });

我知道通常的方式是这样的,这很好用。

    setPersonsState({
      persons: [
        { name : 'Max', age : 28 },
        { name : 'Ati', age : 29 },
        { name : 'Stephanie', age : 26 }
      ]

但我觉得每次手动输入都很难,所以我试着让我的生活更轻松。

    const newState = personState;
    newState.persons[1].name = 'Ati';
    setPersonsState(newState)

这没有用,我不知道为什么。当我 console.log 它们成功更改时,尽管我使用了 set 命令,但由于某种原因状态没有刷新。我还注意到 React 的一些奇怪行为,当我使用这个newState.persons[1].name = 'Ati';命令时,它也改变了personState变量。所以 thepersonStatenewState变量在控制台中都是这样的。

    {persons: Array(3)}
    persons: Array(3)
    0: {name: "Max", age: 28}
    1: {name: "Ati", age: 29}
    2: {name: "Stephanie", age: 26}
    length: 3
    __proto__: Array(0)
    __proto__: Object

我将不胜感激任何帮助或解释为什么这不起作用。

标签: javascriptreactjsreact-hooksstatus

解决方案


当您执行此行时const newState = personState;,您不会将 personState 中的对象复制到 newState,而是引用 personState 并使 newState 引用该对象。

当您对 newState 进行更改时,就好像您正在更改 personState,因为这两个变量的引用是相同的。你直接改变了一个状态对象,这在 React 中是一个禁忌,因为它不符合生命周期,这就是你得到这种奇怪行为的原因。

如果要将对象内容复制到这个新变量中,则需要执行以下操作:

const newState = Object.assign({}, personState)

或使用传播语法

const newState = { ...personState }

之后,您可以使用setPersonState

注意:如果你有嵌套对象,上面给出的这些方法只会进行浅层复制,这意味着只会复制第一级值。

如果您想制作对象的深层副本,您要么必须进行多个对象扩展(这是 redux 状态管理中的常见模式),例如

let state = {a: "val", b: { c: "val" }}

let newState = {
    ...state, 
    b: { 
        ...state.b 
     }
}

或者使用 lodash 的deepClone

例如

var objects = [{ 'a': 1 }, { 'b': 2 }];

var deep = _.cloneDeep(objects);

推荐阅读