我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
当前回答
你应该把new state传递给setState。 新状态的引用必须与旧状态的引用不同。
所以试试这个:
this.setState({
...this.state,
someProperty: {...this.state.someProperty, flag: true},
})
其他回答
const newState = Object.assign({}, this.state);
newState.property.nestedProperty = "new value";
this.setState(newState);
我用了这个方法。
如果你有一个这样的嵌套状态:
this.state = {
formInputs:{
friendName:{
value:'',
isValid:false,
errorMsg:''
},
friendEmail:{
value:'',
isValid:false,
errorMsg:''
}
}
你可以声明handleChange函数来复制当前状态并重新赋值
handleChange(el) {
let inputName = el.target.name;
let inputValue = el.target.value;
let statusCopy = Object.assign({}, this.state);
statusCopy.formInputs[inputName].value = inputValue;
this.setState(statusCopy);
}
这里是带有事件侦听器的HTML
<input type="text" onChange={this.handleChange} " name="friendName" />
这是第一个答案的变体,不需要任何额外的包、库或特殊函数。
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对象。
创建一个状态的副本:
let someProperty = JSON.parse(JSON.stringify(this.state.someProperty))
对该对象进行更改:
someProperty.flag = "false"
现在更新状态
this.setState({someProperty})
为了让事情变得通用,我研究了@ShubhamKhatri和@Qwerty的答案。
状态对象
this.state = {
name: '',
grandParent: {
parent1: {
child: ''
},
parent2: {
child: ''
}
}
};
输入控件
<input
value={this.state.name}
onChange={this.updateState}
type="text"
name="name"
/>
<input
value={this.state.grandParent.parent1.child}
onChange={this.updateState}
type="text"
name="grandParent.parent1.child"
/>
<input
value={this.state.grandParent.parent2.child}
onChange={this.updateState}
type="text"
name="grandParent.parent2.child"
/>
updateState方法
setState作为@ShubhamKhatri的答案
updateState(event) {
const path = event.target.name.split('.');
const depth = path.length;
const oldstate = this.state;
const newstate = { ...oldstate };
let newStateLevel = newstate;
let oldStateLevel = oldstate;
for (let i = 0; i < depth; i += 1) {
if (i === depth - 1) {
newStateLevel[path[i]] = event.target.value;
} else {
newStateLevel[path[i]] = { ...oldStateLevel[path[i]] };
oldStateLevel = oldStateLevel[path[i]];
newStateLevel = newStateLevel[path[i]];
}
}
this.setState(newstate);
}
setState作为@Qwerty的答案
updateState(event) {
const path = event.target.name.split('.');
const depth = path.length;
const state = { ...this.state };
let ref = state;
for (let i = 0; i < depth; i += 1) {
if (i === depth - 1) {
ref[path[i]] = event.target.value;
} else {
ref = ref[path[i]];
}
}
this.setState(state);
}
注意:上述方法不适用于数组