How to delete object from array using object property - React
Solution 1
Two issues there:
You're seeming to try to direct modify
this.state.tasks
. It's important not to do that, never directly modifythis.state
or any object on it. See "Do Not Modify State Directly" in the React documentation for state.-
You're passing an object to
setState
that is derived from the current state. It's important never to do that, too. :-) Instead, passsetState
a function and use the state object it passes you when calling that function. From "State Updates May Be Asynchronous" in the documentation:Because
this.props
andthis.state
may be updated asynchronously, you should not rely on their values for calculating the next state... [Instead]...use a second form ofsetState()
that accepts a function rather than an object.(my emphasis)
I figure your remove
on an array was intended to be hypothetical, but for the avoidance of doubt, arrays don't have a remove
method. In this case, the best thing to do, since we need a new array, is to use filter
to remove all entries that shouldn't still be there.
So:
deleteTask(taskToDelete) {
this.setState(prevState => {
const tasks = prevState.tasks.filter(task => task.name !== taskToDelete);
return { tasks };
});
}
Solution 2
You could simply filter the array :
this.setState(prevState => ({
tasks: prevState.tasks.filter(task => task.name !== 'taskToDelete')
}));
Also when updating based on this.state
, its better to use the function form because setState
is async.
Solution 3
You can implement deleteTask
method as below:
deleteTask(taskToDelete) {
this.setState((prevState, props) => {
const tasks = [...prevState.tasks];
const indexOfTaskToDelete = tasks.findIndex(
task => task.name === taskToDelete
);
tasks.splice(indexOfTaskToDelete, 1);
return { tasks };
});
}
A. Find the index of taskToDelete
.
B. Then use splice
method to delete the item from the collection
C. Then call setState
to update the state with tasks
.
Solution 4
You can use filter to remove one object from an array following the immutable pattern (filter will create a new array) :
deleteTask(taskToDelete) {
const newTaskArray = this.state.tasks.filter(task => task.name !== taskToDelete);
this.setState({ tasks: newTaskArray });
}
Edit : codepend of the solution : https://codepen.io/Dyo/pen/ZvPoYP
Solution 5
You can use higher order
function Array#filter
to delete the task.
let updatedTasks = this.state.tasks.filter(task => task.name !== taskToDelete);
this.setState({ tasks: updatedTasks });
physicsboy
Updated on June 17, 2022Comments
-
physicsboy almost 2 years
I have a todo list that holds a delete button in a grandchild, that when clicked fires an event in the parent - I am wanting this event to delete the array entry corresponding to the grandchild clicked.
Parent (contains the array and my attempt at the function)
const tasks = [ { name: 'task1', isComplete: false }, { name: 'task2', isComplete: true }, { name: 'task3', isComplete: false }, ] // taskToDelete is the name of the task - doesn't contain an object deleteTask(taskToDelete) { this.state.tasks.remove(task => task.name === taskToDelete); this.setState({ tasks: this.state.tasks }); }
Any help would be appreciated