是否可以使用setState更新对象的属性?
类似的东西:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
我试过了:
this.setState({jasper.name : 'someOtherName'});
和此:
this.setState({jasper:{name:'someothername'}})
第一个是语法错误,第二个什么都不做。有什么想法吗?
答案 0 :(得分:308)
有多种方法可以做到这一点。
1-最简单的一个:
首先创建jasper
的副本,然后执行以下更改:
let jasper = Object.assign({}, this.state.jasper); //creating copy of object
jasper.name = 'someothername'; //updating value
this.setState({jasper});
我们也可以像这样编写它来代替使用Object.assign
:
let jasper = {...this.state.jasper};
2-使用spread operator :
this.setState(prevState => ({
jasper: {
...prevState.jasper,
name: 'something'
}
}))
答案 1 :(得分:19)
最快且最易读的方式:
this.setState({...this.state.jasper, name: 'someothername'});
Althought this.state.jasper
已包含名称属性,后者name: 'someothername'
已被使用。
答案 2 :(得分:15)
在这里使用spread运算符和一些ES6
this.setState({
jasper: {
...this.state.jasper,
name: 'something'
}
})
答案 3 :(得分:6)
我使用了这个解决方案。
如果你有这样的嵌套状态:
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。确保使用与州对象相同的名称(在这种情况下' friendName')
<input type="text" onChange={this.handleChange} " name="friendName" />
答案 4 :(得分:5)
尝试一下,它应该可以正常工作
this.setState(Object.assign(this.state.jasper,{name:'someOtherName'}));
答案 5 :(得分:3)
第一种情况确实是语法错误。
由于我无法看到您组件的其余部分,因此很难理解为什么您在此处将状态中的对象嵌套。将对象嵌套在组件状态中不是一个好主意。尝试将初始状态设置为:
this.state = {
name: 'jasper',
age: 28
}
这样,如果你想更新名字,你可以打电话:
this.setState({
name: 'Sean'
});
这会实现你的目标吗?
对于更大,更复杂的数据存储,我会使用像Redux这样的东西。但那要先进得多。
组件状态的一般规则是仅使用它来管理组件的UI状态(例如,活动,计时器等)
查看以下参考资料:
答案 6 :(得分:2)
我知道这里有很多答案,但是令我惊讶的是,没有一个在setState之外创建新对象的副本,然后只是setState({newObject})。干净,简洁,可靠。因此,在这种情况下:
const jasper = { ...this.state.jasper, name: 'someothername' }
this.setState(prevState => ({ jasper }))
或者对于动态属性(对于表单非常有用)
const jasper = { ...this.state.jasper, [VarRepresentingPropertyName]: 'new value' }
this.setState(prevState => ({ jasper }))
答案 7 :(得分:1)
this.state = {
objName: {
propertyOne: "",
propertyTwo: ""
}
};
this.setState(prevState => ({
objName: {
...prevState.objName,
propertyOne: "Updated Value",
propertyTwo: "Updated value"
}
}));
答案 8 :(得分:1)
试试这个:
const { jasper } = this.state; //Gets the object from state
jasper.name = 'A new name'; //do whatever you want with the object
this.setState({jasper}); //Replace the object in state
答案 9 :(得分:0)
通过使用 input html input name 属性,我们可以采用更动态的方法来更新对象属性。
<input type="text" name="fname" handleChange={(e: any) => { updatePerson(e) }}/>
<input type="text" name="lname" handleChange={(e: any) => { updatePerson(e) }}/>
React / TSX object.assign
const [person, setPerson] = useState<IPerson>({});
function updatePerson(e: React.ChangeEvent<HTMLInputElement>): void {
const { name, value } = e.currentTarget;
setPerson(prevState => {
const newState = Object.assign(person, { [name]: value })
return { ...prevState, ...newState };
});
}
答案 10 :(得分:0)
例如假设您的状态对象是
serviceDays: {
Sunday: true,
Monday: true,
Tuesday: false,
Wednesday: true,
Thurday: false,
Friday: true,
Saturday: true
}
所以你可以通过以下方式更新
const onDayClick = day => {
const { serviceDays } = this.state
this.setState(prevState => ({
serviceDays: {
...prevState.serviceDays,
[day]: serviceDays[day] ? false : true
}
}))
}
答案 11 :(得分:0)
您的第二种方法不起作用,因为{name: 'someothername'}
等于{name: 'someothername', age: undefined}
,因此undefined
将覆盖原始年龄值。
当要更改嵌套对象的状态时,最好的方法是Immutable.js
this.state = {
jasper: Record({name: 'jasper', age: 28})
}
const {jasper} = this.state
this.setState({jasper: jasper.set(name, 'someothername')})
答案 12 :(得分:0)
此设置对我有用:
let newState = this.state.jasper;
newState.name = 'someOtherName';
this.setState({newState: newState});
console.log(this.state.jasper.name); //someOtherName
答案 13 :(得分:0)
这是使用immer immutabe实用程序的另一种解决方案,非常适合轻松嵌套的深层对象,您无需担心突变
this.setState(
produce(draft => {
draft.jasper.name = 'someothername
})
)
答案 14 :(得分:0)
不使用Async和Await使用此...
funCall(){
this.setState({...this.state.jasper, name: 'someothername'});
}
如果您将Async和Await一起使用,请使用此...
async funCall(){
await this.setState({...this.state.jasper, name: 'someothername'});
}
答案 15 :(得分:0)
简单而动态的方式。
这可以完成工作,但是您需要将所有id都设置为父对象,这样父对象将指向对象的名称,即id =“ jasper”,并在其中命名输入元素=属性的名称。碧玉。
throws.push(throws.front());
throws.pop();
答案 16 :(得分:0)
您可以尝试以下操作: (注意:输入标签的名称===对象的字段)
<input name="myField" type="text"
value={this.state.myObject.myField}
onChange={this.handleChangeInpForm}></input>
-----------------------------------------------------------
handleChangeInpForm = (e) => {
let newObject = this.state.myObject;
newObject[e.target.name] = e.target.value;
this.setState({
myObject: newObject
})
}
答案 17 :(得分:0)
此外,如果您不想复制所有“状态”对象,则遵循Alberto Piras解决方案:
handleChange(el) {
let inputName = el.target.name;
let inputValue = el.target.value;
let jasperCopy = Object.assign({}, this.state.jasper);
jasperCopy[inputName].name = inputValue;
this.setState({jasper: jasperCopy});
}
答案 18 :(得分:0)
另一种选择:从 Jasper 对象中定义变量,然后调用变量。
点差操作员:ES6
this.state = { jasper: { name: 'jasper', age: 28 } }
let foo = "something that needs to be saved into state"
this.setState(prevState => ({
jasper: {
...jasper.entity,
foo
}
})
答案 19 :(得分:-1)
您可以尝试以下操作:
this.setState(prevState => {
prevState = JSON.parse(JSON.stringify(this.state.jasper));
prevState.name = 'someOtherName';
return {jasper: prevState}
})
或其他财产:
this.setState(prevState => {
prevState = JSON.parse(JSON.stringify(this.state.jasper));
prevState.age = 'someOtherAge';
return {jasper: prevState}
})
或者您可以使用handleChage函数:
handleChage(event) {
const {name, value} = event.target;
this.setState(prevState => {
prevState = JSON.parse(JSON.stringify(this.state.jasper));
prevState[name] = value;
return {jasper: prevState}
})
}
和HTML代码:
<input
type={"text"}
name={"name"}
value={this.state.jasper.name}
onChange={this.handleChange}
/>
<br/>
<input
type={"text"}
name={"age"}
value={this.state.jasper.age}
onChange={this.handleChange}
/>