我想只更新一个对象的值,但更新一个对象的值,更新所有对象的值。
let default = {
name: '',
age: ''
}
this.state = {
values: Array(2).fill(default)
}
updateName (event) {
let index = event.target.id,
values = this.state.values;
values[index].name = event.target.value;
this.setState ({
values: values
});
}
该代码中存在四个重要问题。
setState
。无论何时基于现有状态设置状态(并且您在values
上间接设置this.state.values
),都必须使用setState
的函数回调版本。更多:State Updates May Be Asynchronousthis.state.values
中持有的对象;相反,您必须复制该对象并进行修改。更多:Do Not Modify State Directlydefault
是一个keyword(即使它目前没有使用),你不能用它作为标识符。让我们用defaultValue
代替。以下是解决这三种问题的一种方法(见评论):
// #4 - `default` is a keyword
let defaultValue = {
name: '',
age: ''
};
this.state = {
// #1 - copy default, don't use it directly
values: [
Object.assign({}, defaultValue),
Object.assign({}, defaultValue)
] // <=== Side note - no ; here!
}
updateName (event) {
let index = event.target.id,
// #2 - state updates working from current state MUST use
// the function callback version of setState
this.setState(prevState => {
// #3 - don't modify state directly - copy the array...
values = prevState.values.slice();
// ...and the object, doing the update
values[index] = {...values[index], name: event.target.value};
return {values};
});
}
注意上面的这一行:
values[index] = {...values[index], name: event.target.value};
...使用来自this JavaScript enhancement proposal的语法,目前处于第4阶段(它将在ES2018快照规范中)并且通常在React构建环境中启用。
我会使用Array.prototype.map
函数与object spread syntax (stage 4)的组合:
请注意,我将default
对象的名称更改为obj
。
default
是一个reserved key word in javascript
let obj = {
name: '',
age: ''
}
this.state = {
values: Array(2).fill(obj)
}
updateName(event){
const {id, value} = event.target;
this.setState(prev => {
const {values} = prev;
const nextState = values.map((o,idx) => {
if(idx !== id)
return o; // not our object, return as is
return{
...o,
name: value;
}
});
return{
values: nextState
}
});
}