J'essaie de copier un objet d'état:
@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]);
}
état code > l'objet est également modifié. D'après ce que j'ai lu, je ne devrais pas muter un objet state mais seulement le changer avec setState .
Comment puis-je corriger cela? p>
3 Réponses :
Vous obtenez ce comportement, car le
let requestApprovalClone = {... this.state.requestApproval}
n'est qu'une copie superficielle des données, votre attachments possède des objets imbriqués et conserve la même référence et donc lors de sa modification, l'objet cloné est modifié et l'état aussi.
Pour éviter cela, vous pouvez effectuer une autre copie de votre propriété attachements comme ceci:
let attachments = [...requestApprovalClone[strings.Attachments]];
_.remove(attachments, function (attachment) {
return attachment.FileName === attachmentName;
});
La modification du contenu de la variable des pièces jointes n'affectera plus l'état.
vous peut en savoir plus sur ce comportement ici
Vous pouvez avoir quelque chose comme:
let requestApprovalClone = Object.assign({},this.state.requestApproval);
requestApprovalClone.strings.Attachments = requestApprovalClone.strings.Attachments.slice(); // will create a shallow copy of this array as well
_.remove(requestApprovalClone[strings.Attachments], (attachment: any) => {
return attachment.FileName === attachmentName;
})
this.setState({
requestApproval:requestApprovalClone
})// If you want to update that in state back
Cela dépend de la façon dont JS gère ses références const .
Pour ceux qui se sentent aventureux:
let requestApprovalClone = JSON.parse(JSON.stringify(this.state.requestApproval));
// modify requestApprovalClone ...
this.setState({
requestApproval:requestApprovalClone
})
Ce serait être intéressant si Object.assign ({}, this.state.requestApproval); est plus rapide que tout le JSON stringify / parse stuff ou vice versa