我试图通过使用这样的嵌套属性来组织我的状态:

this.state = {
   someProperty: {
      flag:true
   }
}

但是像这样更新状态,

this.setState({ someProperty.flag: false });

是行不通的。怎样才能正确地做到这一点呢?


当前回答

虽然你问的是基于类的React组件的状态,但useState钩子也存在同样的问题。更糟糕的是:useState钩子不接受部分更新。所以当useState钩子被引入时,这个问题就变得非常相关了。

我决定发布以下答案,以确保这个问题涵盖了使用useState钩子的更现代的场景:

如果你有:

const [state, setState] = useState({
  someProperty: {
    flag: true,
    otherNestedProp: 1
  },
  otherProp: 2
})

你可以通过克隆当前数据并修补所需的数据段来设置嵌套属性,例如:

setState(current => { ...current,
  someProperty: { ...current.someProperty,
    flag: false
  }
});

或者您可以使用Immer库来简化对象的克隆和修补。

或者你可以使用Hookstate库(免责声明:我是一名作家)来简单地管理复杂的(本地和全局)状态数据,并提高性能(阅读:不用担心渲染优化):

import { useHookstate } from '@hookstate/core'

const state = useHookstate({
  someProperty: {
    flag: true,
    otherNestedProp: 1
  },
  otherProp: 2
})

获取要渲染的字段:

state.someProperty.flag.get()
// or 
state.get().someProperty.flag

设置嵌套字段:

state.someProperty.flag.set(false)

下面是Hookstate示例,其中的状态被深度递归嵌套在树状数据结构中。

其他回答

stateUpdate = () => {
    let obj = this.state;
    if(this.props.v12_data.values.email) {
      obj.obj_v12.Customer.EmailAddress = this.props.v12_data.values.email
    }
    this.setState(obj)
}

如果你正在使用ES2015,你可以访问Object.assign。您可以使用它来更新嵌套对象。

this.setState({
  someProperty: Object.assign({}, this.state.someProperty, {flag: false})
});

您将更新的属性与现有属性合并,并使用返回的对象更新状态。

编辑:将一个空对象作为目标添加到赋值函数中,以确保状态不会像carkod指出的那样直接发生突变。

这显然不是正确或最好的方法,但在我看来,这是更清晰的:

this.state.hugeNestedObject = hugeNestedObject; 
this.state.anotherHugeNestedObject = anotherHugeNestedObject; 

this.setState({})

然而,React本身应该迭代思想嵌套对象,并相应地更新状态和DOM。

setInputState((pre)=> ({...pre,[parentKey]: {...pre[parentKey], [childKey]: value}}));

我喜欢这个

如果你在你的项目中使用formik,它有一些简单的方法来处理这些东西。下面是使用formik最简单的方法。

首先在formik initivalues属性或react中设置初始值。状态

这里,初始值是在react状态下定义的

   state = { 
     data: {
        fy: {
            active: "N"
        }
     }
   }

在formik initiValues属性中定义以上的initialValues字段

<Formik
 initialValues={this.state.data}
 onSubmit={(values, actions)=> {...your actions goes here}}
>
{({ isSubmitting }) => (
  <Form>
    <Field type="checkbox" name="fy.active" onChange={(e) => {
      const value = e.target.checked;
      if(value) setFieldValue('fy.active', 'Y')
      else setFieldValue('fy.active', 'N')
    }}/>
  </Form>
)}
</Formik>

制作一个控制台来检查状态更新为字符串而不是布尔值formik setFieldValue函数来设置状态或使用react调试器工具来查看formik状态值的变化。