Reputation: 699
I am trying to copy a state object:
@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]);
}
The state
object is being altered too. From what I have read, I shouldn't mutate a state
object but only change it with setState
.
How can I correct this?
Upvotes: 7
Views: 14421
Reputation: 3962
It has to to with the way that JS handles their const
references.
For those who feel adventerous:
let requestApprovalClone = JSON.parse(JSON.stringify(this.state.requestApproval));
// modify requestApprovalClone ...
this.setState({
requestApproval:requestApprovalClone
})
It would be interesting if Object.assign({},this.state.requestApproval);
is faster than the whole JSON stringify/parse stuff or vice versa
Upvotes: 5
Reputation: 870
You can have something like:
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
Upvotes: 1
Reputation: 1533
You are getting that behavior, because the
let requestApprovalClone = {... this.state.requestApproval}
is only shallow copying the data, your attachments
property has some nested objects and it keeps the same reference and therefore when changing it, the cloned object gets altered and the state too.
To avoid that, you can perform another copy of your attachments
property like this :
let attachments = [...requestApprovalClone[strings.Attachments]];
_.remove(attachments, function (attachment) {
return attachment.FileName === attachmentName;
});
Changing the attachments variable content won't afftect the state anymore.
you can read more about that behavior here
Upvotes: 8