'Deleting keys from dictionary object in component's state [React]
I'm having trouble updating my component's state in my delete function. Within the state there is a dictionary this.state.tasks. I want to remove all the keys in the dictionary that exist in an array of user selected tasks, this.state.selected. No matter what I do I can't seem to achieve the desired behavior.
Here is what I've tried so far:
Making a reference copy of this.state.tasks, modifying it, then setting state back to it.
deleteTask() {
var tasks_copy = this.state.tasks;
this.state.selected.forEach((task_name) => {
delete tasks_copy[task_name];
});
this.setState({
...this.state,
selected: [],
allSelected: false,
tasks: tasks_copy,
});
ipcRenderer.send("REACT_MODIFY_DATA", {
file: "tasks",
data: JSON.stringify(this.state.tasks),
});
}
This is what brought me to my original problem. I know this is not correct because the state is immutable and I'm directly modifying it with this method (which led to incorrect rendering without a refresh). Interestingly enough, this.state.selected and this.state.allSelected are not modified, so it would seem this.setState is not working, but instead that I just modified this.state.tasks through the reference copy.
Making a shallow copy of this.state.tasks, modifying it, then setting state to modified copy:
deleteTask() {
// Create a shallow copy of state
var tasks_copy = _.clone(this.state.tasks);
this.state.selected.forEach((task_name) => {
delete tasks_copy[task_name];
});
this.setState({
...this.state,
selected: [],
allSelected: false,
tasks: tasks_copy,
});
ipcRenderer.send("REACT_MODIFY_DATA", {
file: "tasks",
data: JSON.stringify(this.state.tasks),
});
}
This does not successfully update the state. I can see that tasks_copy is changed exactly how I want, but the state does not reflect any changes.
Trying a deep copy of this.state.tasks, modifying it, and setting state back to modified copy:
deleteTask() {
// Create a deep copy of state
var tasks_copy = JSON.parse(JSON.stringify(this.state.tasks));
this.state.selected.forEach((task_name) => {
delete tasks_copy[task_name];
});
this.setState({
...this.state,
selected: [],
allSelected: false,
tasks: tasks_copy,
});
ipcRenderer.send("REACT_MODIFY_DATA", {
file: "tasks",
data: JSON.stringify(this.state.tasks),
});
}
This has the same result as a shallow copy. There is no change to the state whatsoever.
Trying to use a filter and reduce directly in setState:
deleteTask() {
this.state.selected.forEach((task_name) => {
this.setState({
...this.state,
selected: [],
allSelected: false,
tasks: Object.keys(this.state.tasks)
.filter((key) => key !== task_name)
.reduce((result, current) => {
result[current] = this.state.tasks[current];
return result;
}, {}),
});
});
ipcRenderer.send("REACT_MODIFY_DATA", {
file: "tasks",
data: JSON.stringify(this.state.tasks),
});
}
This does not update the state at all. None of the changes made in setState persist. There also must be a better way so that I could remove keys that match an array of values instead of a single value at a time...
At this point I have even tried using this.setState to make this.state.tasks simply an empty dictionary {}, and this still did not work?? Perhaps I am misunderstanding something about updating fields of the state. Please help!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
