我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
当前回答
尽管嵌套并不是处理组件状态的真正方式,但有时对于单层嵌套来说很容易。
对于这样一个州来说
state = {
contact: {
phone: '888-888-8888',
email: 'test@test.com'
}
address: {
street:''
},
occupation: {
}
}
我使用的一个可重用的方法是这样的。
handleChange = (obj) => e => {
let x = this.state[obj];
x[e.target.name] = e.target.value;
this.setState({ [obj]: x });
};
然后为你想要处理的每个嵌套传递obj名称…
<TextField
name="street"
onChange={handleChange('address')}
/>
其他回答
为了为嵌套对象设置setState,你可以遵循下面的方法,因为我认为setState不处理嵌套更新。
var someProperty = {...this.state.someProperty}
someProperty.flag = true;
this.setState({someProperty})
其思想是创建一个虚拟对象,对其执行操作,然后用更新的对象替换组件的状态
现在,展开操作符只创建对象的一层嵌套副本。如果你的状态是高度嵌套的,比如:
this.state = {
someProperty: {
someOtherProperty: {
anotherProperty: {
flag: true
}
..
}
...
}
...
}
你可以在每一层使用展开运算符setState
this.setState(prevState => ({
...prevState,
someProperty: {
...prevState.someProperty,
someOtherProperty: {
...prevState.someProperty.someOtherProperty,
anotherProperty: {
...prevState.someProperty.someOtherProperty.anotherProperty,
flag: false
}
}
}
}))
然而,随着状态嵌套越来越多,上面的语法会变得越来越糟糕,因此我建议你使用不可变性帮助包来更新状态。
关于如何使用immutability-helper更新状态,请参阅此回答。
我发现这对我很有用,在我的案例中有一个项目表单,例如,你有一个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>
)
让我知道!
我们使用Immer https://github.com/mweststrate/immer来处理这类问题。
只是在我们的一个组件中替换了这段代码
this.setState(prevState => ({
...prevState,
preferences: {
...prevState.preferences,
[key]: newValue
}
}));
用这个
import produce from 'immer';
this.setState(produce(draft => {
draft.preferences[key] = newValue;
}));
使用immer,您可以将您的状态作为“普通对象”处理。 神奇的事情发生在代理对象的幕后。
使用箭头函数代替,这应该做的把戏。
setItems((prevState) => {
prevState.nestedData = newNestedData;
prevState.nestedData1 = newNestedData1;
});
不要忘记使用箭头函数(prevState) =>{更新js赋值语句…}
你可以用对象展开来做这个 代码:
this.setState((state)=>({ someProperty:{...state.someProperty,flag:false}})
这将适用于更多嵌套的属性