考虑一个关键培训师应用程序的简单组件。在成长为复杂的应用程序之前,它可以具有以下状态:
constructor() {
super();
this.state = {
task: {
line: 'fjj jfjjf fj fffj fjjfj jffj f',
position: 0,
mistakeAtCurrentPosition: false
}
};
...
}
现在我有一个按键处理程序,因此当用户正确按下它时,我想进行更改
{
task: {
line: 'fjj jfjjf fj fffj fjjfj jffj f',
position: 10,
mistakeAtCurrentPosition: false
}
};
到
{
task: {
line: 'fjj jfjjf fj fffj fjjfj jffj f',
position: 11,
mistakeAtCurrentPosition: false
}
};
这太冗长又脆弱:
this.setState(prevState => {
return {
task: {
line: prevState.task.line,
position: prevState.task.position + 1,
mistakeAtCurrentPosition: false
}
}
})
我知道state updates are merged,但据我所知,它们仅在嵌套的第一级上合并,就像我的状态是
{
line: 'fjj jfjjf fj fffj fjjfj jffj f',
position: 11,
mistakeAtCurrentPosition: false
};
我能做
this.setState(prevState => {
return {
position: prevState.task.position + 1,
}
})
(但如果我尝试
this.setState(prevState => {
return {
task: {
position: prevState.task.position + 1,
}
}
})
该应用程序混乱了,好像state.task.line
不再定义了
但是由于某种原因(会有其他任务等),我创建了一个嵌套的task
属性,那么如何只更新state.task.position
位呢?
我也尝试过
this.setState(prevState => {
prevState.task.position++;
return prevState;
})
但是应用无法通过这种方式编译。
实际上,PS有时会合规,但不能以可重复的方式工作。 adiga注意到prevState
是对当前状态的引用,不应忽略当前状态,因此应避免这种方法。
答案 0 :(得分:2)
您可以执行以下操作:
this.setState(prevState => {
return {
...prevState,
task: { ...prevState.task, position: prevState.task.position + 1 }
}
})