我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
当前回答
我发现这对我很有用,在我的案例中有一个项目表单,例如,你有一个id和一个名称,我宁愿为一个嵌套的项目维护状态。
return (
<div>
<h2>Project Details</h2>
<form>
<Input label="ID" group type="number" value={this.state.project.id} onChange={(event) => this.setState({ project: {...this.state.project, id: event.target.value}})} />
<Input label="Name" group type="text" value={this.state.project.name} onChange={(event) => this.setState({ project: {...this.state.project, name: event.target.value}})} />
</form>
</div>
)
让我知道!
其他回答
我看到每个人都给出了基于类的组件状态更新解决方案,这是预期的,因为他要求,但我试图给钩子相同的解决方案。
const [state, setState] = useState({
state1: false,
state2: 'lorem ipsum'
})
现在,如果你想改变嵌套对象键state1,那么你可以做以下任何一项:
过程1
let oldState = state;
oldState.state1 = true
setState({...oldState);
流程2
setState(prevState => ({
...prevState,
state1: true
}))
我最喜欢过程。
这是第一个答案的变体,不需要任何额外的包、库或特殊函数。
state = {
someProperty: {
flag: 'string'
}
}
handleChange = (value) => {
const newState = {...this.state.someProperty, flag: value}
this.setState({ someProperty: newState })
}
为了设置特定嵌套字段的状态,您已经设置了整个对象。为此,我创建了一个变量newState,并首先使用ES2015扩展操作符将当前状态的内容扩散到该变量中。然后,我用新值替换了this.state.flag的值(因为我在将当前状态扩展到对象后设置了flag: value,所以当前状态下的flag字段将被覆盖)。然后,我简单地将someProperty的状态设置为newState对象。
你可以用对象展开来做这个 代码:
this.setState((state)=>({ someProperty:{...state.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示例,其中的状态被深度递归嵌套在树状数据结构中。
你应该把new state传递给setState。 新状态的引用必须与旧状态的引用不同。
所以试试这个:
this.setState({
...this.state,
someProperty: {...this.state.someProperty, flag: true},
})