是否可以使用setState更新对象的属性?
就像是:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
Run Code Online (Sandbox Code Playgroud)
我试过了:
this.setState({jasper.name: 'someOtherName'});
Run Code Online (Sandbox Code Playgroud)
还有这个:
this.setState({jasper: {name: 'someothername'}})
Run Code Online (Sandbox Code Playgroud)
第一个是语法错误,第二个什么都不做.有任何想法吗?
May*_*kla 440
有多种方法可以做到这一点.
1-最简单的一个:
首先创建一个副本,setState
然后执行以下更改:
this.setState(prevState => {
let jasper = Object.assign({}, prevState.jasper); // creating copy of state variable jasper
jasper.name = 'someothername'; // update the name property, assign a new value
return { jasper }; // return new object jasper object
})
Run Code Online (Sandbox Code Playgroud)
而不是使用jasper
我们也可以像这样写:
let jasper = { ...prevState.jasper };
Run Code Online (Sandbox Code Playgroud)
2-使用扩展运算符:
this.setState(prevState => ({
jasper: { // object that we want to update
...prevState.jasper, // keep all other key-value pairs
name: 'something' // update the value of specific key
}
}))
Run Code Online (Sandbox Code Playgroud)
Raj*_*sit 29
使用钩子我们可以这样做
const [student, setStudent] = React.useState({name: 'jasper', age: 28});
setStudent((prevState) => ({
...prevState,
name: 'newName',
}));
Run Code Online (Sandbox Code Playgroud)
man*_*nok 27
最快,最易读的方式:
this.setState({...this.state.jasper, name: 'someothername'});
Run Code Online (Sandbox Code Playgroud)
虽然this.state.jasper
已经包含一个名称属性,后者name: 'someothername'
可以使用.
小智 26
在这里使用扩展运算符和一些ES6
this.setState({
jasper: {
...this.state.jasper,
name: 'something'
}
})
Run Code Online (Sandbox Code Playgroud)
col*_*ick 23
我知道这里有很多答案,但我很惊讶他们都没有在 setState 之外创建新对象的副本,然后简单地 setState({newObject})。干净、简洁、可靠。所以在这种情况下:
const jasper = { ...this.state.jasper, name: 'someothername' }
this.setState(() => ({ jasper }))
Run Code Online (Sandbox Code Playgroud)
或者对于动态属性(对表单非常有用)
const jasper = { ...this.state.jasper, [VarRepresentingPropertyName]: 'new value' }
this.setState(() => ({ jasper }))
Run Code Online (Sandbox Code Playgroud)
我用过这个解决方案.
如果您有这样的嵌套状态:
this.state = {
formInputs:{
friendName:{
value:'',
isValid:false,
errorMsg:''
},
friendEmail:{
value:'',
isValid:false,
errorMsg:''
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以声明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);
}
Run Code Online (Sandbox Code Playgroud)
这里是带有事件监听器的html.确保使用与状态对象相同的名称(在本例中为'friendName')
<input type="text" onChange={this.handleChange} " name="friendName" />
Run Code Online (Sandbox Code Playgroud)
创建状态对象
this.state = {
objName: {
propertyOne: "",
propertyTwo: ""
}
};
Run Code Online (Sandbox Code Playgroud)
使用更新状态setState
this.setState(prevState => ({
objName: {
...prevState.objName,
propertyOne: "Updated Value",
propertyTwo: "Updated value"
}
}));
Run Code Online (Sandbox Code Playgroud)
在功能组件中使用钩子:
const [state, setState] = useState({jasper: { name: 'jasper', age: 28 }})
const nameChangeHandler = () => {
setState(prevState => ({
...prevState,
prevState.jasper.name = "Anurag",
prevState.jasper.age = 28
})
)
}
Run Code Online (Sandbox Code Playgroud)
在这些情况下,建议使用基于回调的方法来更新状态,因为使用这种方法可以确保之前的状态完全更新,并且我们根据之前更新的状态进行更新。
小智 6
试试这个,它应该工作正常
this.setState(Object.assign(this.state.jasper,{name:'someOtherName'}));
Run Code Online (Sandbox Code Playgroud)
这是使用immer immutabe 实用程序的另一种解决方案,非常适合轻松深度嵌套的对象,并且您不应该关心突变
this.setState(
produce(draft => {
draft.jasper.name = 'someothername'
})
)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
189456 次 |
最近记录: |