如何在React中对状态(嵌套属性)进行小的更新?

时间:2019-02-07 19:34:20

标签: javascript reactjs

考虑一个关键培训师应用程序的简单组件。在成长为复杂的应用程序之前,它可以具有以下状态:

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是对当前状态的引用,不应忽略当前状态,因此应避免这种方法。

1 个答案:

答案 0 :(得分:2)

您可以执行以下操作:

this.setState(prevState => {
    return {
        ...prevState, 
        task: { ...prevState.task, position: prevState.task.position + 1 }
    }
})