复制 React State 对象;修改复制的对象会改变状态对象

Hol*_*515 5 javascript reactjs

我正在尝试复制一个状态对象:

@boundMethod
private _onClickDeleteAttachment(attachmentName: string): void {
    console.log("_onClickDeleteAttachment | this.state.requestApproval[strings.Attachments]: ", this.state.requestApproval[strings.Attachments]);

    let requestApprovalClone = {... this.state.requestApproval}

    if (requestApprovalClone === this.state.requestApproval) {
        console.log("they are ===");
    }
    else {
        console.log(" they are not ===");
    }

    _.remove(requestApprovalClone[strings.Attachments], (attachment: any) => {
        return attachment.FileName === attachmentName;
    })

    console.log("_onClickDeleteAttachment | this.state.requestApproval[strings.Attachments]: ", this.state.requestApproval[strings.Attachments]);
    console.log("_onClickDeleteAttachment | requestApprovalClone[strings.Attachments]: ", requestApprovalClone[strings.Attachments]);
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

state对象被修改过。从我读过的内容来看,我不应该改变一个state对象,而只能用setState.

我该如何纠正?

Abd*_*MEL 6

你得到了这种行为,因为

let requestApprovalClone = {... this.state.requestApproval}

只是浅复制数据,您的attachments属性有一些嵌套对象并且它保持相同的引用,因此在更改它时,克隆的对象和状态也会改变。

为避免这种情况,您可以attachments像这样执行您的财产的另一个副本:

let attachments = [...requestApprovalClone[strings.Attachments]];
_.remove(attachments, function (attachment)  {
  return attachment.FileName === attachmentName;
});
Run Code Online (Sandbox Code Playgroud)

更改附件变量内容将不再影响状态。

您可以在此处阅读有关该行为的更多信息


G43*_*eli 5

这与 JS 处理引用的方式有关const

对于那些喜欢冒险的人:

let requestApprovalClone = JSON.parse(JSON.stringify(this.state.requestApproval));

// modify requestApprovalClone ...

this.setState({
  requestApproval:requestApprovalClone
})
Run Code Online (Sandbox Code Playgroud)

Object.assign({},this.state.requestApproval);如果比整个 JSON 字符串化/解析的东西更快,或者反之亦然,那就很有趣了