Answers:
有多种方法可以执行此操作,因为状态更新是异步操作,因此要更新状态对象,我们需要使用带有updater函数setState
。
1-最简单的一个:
首先创建的副本,jasper
然后执行以下更改:
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
})
除了使用,Object.assign
我们还可以这样写:
let jasper = { ...prevState.jasper };
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
}
}))
注意: Object.assign
并且Spread Operator
仅创建浅表副本,因此,如果您定义了嵌套对象或对象数组,则需要使用其他方法。
假设您将状态定义为:
this.state = {
food: {
sandwich: {
capsicum: true,
crackers: true,
mayonnaise: true
},
pizza: {
jalapeno: true,
extraCheese: false
}
}
}
要更新披萨对象的ExtraCheese:
this.setState(prevState => ({
food: {
...prevState.food, // copy all other key-value pairs of food object
pizza: { // specific object of food object
...prevState.food.pizza, // copy all pizza key-value pairs
extraCheese: true // update value of specific key
}
}
}))
假设您有一个待办事项应用程序,并且您正在以这种形式管理数据:
this.state = {
todoItems: [
{
name: 'Learn React Basics',
status: 'pending'
}, {
name: 'Check Codebase',
status: 'pending'
}
]
}
要更新任何待办事项对象的状态,请在数组上运行一个映射并检查每个对象的某些唯一值,如果为condition=true
,则返回具有更新值的新对象,否则返回相同的对象。
let key = 2;
this.setState(prevState => ({
todoItems: prevState.todoItems.map(
el => el.key === key? { ...el, status: 'done' }: el
)
}))
建议:如果对象没有唯一值,则使用数组索引。
jasper
对象中删除其他属性,这样做console.log(jasper)
您只会看到一个键name
,年龄将不存在:)
jasper
的object
,如果是,这种方法是正确的,而不管是否最好,可能还有其他更好的解决方案:)
Object.assign
传播运算符,也不传播深度复制属性。通过这种方式,你应该使用像lodash解决方法deepCopy
等
let { jasper } = this.state
?
我用了这个解决方案。
如果您有这样的嵌套状态:
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" />
statusCopy.formInputs[inputName] = inputValue;
我知道这里有很多答案,但是令我惊讶的是,没有一个在setState之外创建新对象的副本,然后只是setState({newObject})。干净,简洁,可靠。因此,在这种情况下:
const jasper = { ...this.state.jasper, name: 'someothername' }
this.setState(() => ({ jasper }))
或用于动态属性(对于表单非常有用)
const jasper = { ...this.state.jasper, [VarRepresentingPropertyName]: 'new value' }
this.setState(() => ({ jasper }))
试试这个,应该工作正常
this.setState(Object.assign(this.state.jasper,{name:'someOtherName'}));
Object.assign({}, this.state.jasper, {name:'someOtherName'})
第一种情况确实是语法错误。
由于看不到组件的其余部分,因此很难在这里看到为什么将对象嵌套在状态中。将对象嵌套在组件状态不是一个好主意。尝试将您的初始状态设置为:
this.state = {
name: 'jasper',
age: 28
}
这样,如果您想更新名称,则可以调用:
this.setState({
name: 'Sean'
});
这样可以实现您的目标吗?
对于更大,更复杂的数据存储,我将使用Redux之类的东西。但这要先进得多。
具有组件状态的一般规则是仅使用它来管理组件的UI状态(例如活动状态,计时器等)。
查看以下参考:
简单而动态的方式。
这样就可以完成工作,但是您需要将所有id都设置为父对象,这样父对象将指向对象的名称,即id =“ jasper”,并在对象jasper内将输入元素的名称=属性命名。
handleChangeObj = ({target: { id , name , value}}) => this.setState({ [id]: { ...this.state[id] , [name]: value } });
您可以尝试以下操作:(注意:输入标记的名称===对象的字段)
<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
})
}
这是用另一种解决办法音麦 immutabe实用,非常适合轻松深度嵌套的对象,你不应该在乎突变
this.setState(
produce(draft => {
draft.jasper.name = 'someothername
})
)
您可以尝试以下操作:
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}
/>
age
属性jasper
。