Reputation: 1977
I created a todo list using React, everything works fine until I tried to implement a delete function.
Whenever I try to delete an item, React would delete everything else but that item instead. I checked my code and I couldn't figure out what might be the cause. Console log returns the correct object when an item is click. I have a feeling that this might have to do with the key value not being unique or how my code is factored. To better illustrate the problem I encountered, I've created a codepen.
Upvotes: -1
Views: 1723
Reputation: 1321
Replace your deleteHandler Funtion with this.
deleteHandler = index => {
const tasks = this.state.tasks.slice();
tasks.splice(index, 1);
this.setState({
tasks
});
};
It's better approach when set/reset/modify state you must create a copy of state by using slice method then delete from the copied list then setState.
Upvotes: 1
Reputation: 695
For now, your delete function is working as expected: return updated state.tasks which contains an element you clicked. Use this instead:
deleteHandler = index => {
this.setState({
tasks: this.state.tasks.filter((task) => task.value !== index)
});
};
It works correctly.
Upvotes: 1
Reputation: 4811
This is because your deleteHandler
in the Todo
component uses .splice
... which returns the removed element.
Your code:
deleteHandler = index => {
const tasks = this.state.tasks.splice(index, 1);
this.setState({
tasks
});
};
You want to do something like in this codepen.
deleteHandler = index => {
const newTasks = this.state.tasks.filter((task, tIndex) => {
return index !== tIndex;
});
this.setState({
tasks: newTasks
});
};
Upvotes: 4
Reputation: 582
splice()
actually does two things, in practice it sort of has a side effect and a return. You were expecting the original array to return (understandably) but splice() actually returns the array of the items chopped from the initial array (mdn). So the variable tasks
was being set to an array of todo list items chopped out of the initial state of todo list items.
What you want is essentially just the side effect. You can see an updated CodeSandbox here, but all I did was create a copy of the current state, then use splice() on that copy -- at which point we're only using the side-effect aspect of splice().
const tasks = this.state.tasks.slice(); // copy of current todo list
tasks.splice(index, 1); // "splice" out the list item we want to delete, but don't return a new list
this.setState({ tasks });
Upvotes: 4