Reputation: 855
I'm learning react and I'm trying to get my head around it so I'm trying to practice a little bit. so I decided to delete an element from an array. so here is what I'm trying to do: when the user clicks an item in the UI I use index of that element to delete it and update the state and here's the code that I used.
class App extends Component {
state={
persons: [
{ id: 'asfa1', name: 'Max', age: 28 },
{ id: 'vasdf1', name: 'Manu', age: 29 },
{ id: 'asdf11', name: 'Stephanie', age: 26 },
],
showPersons:false,
}
deletePersonsHandler=(index)=>{
const persons= [...this.state.persons];
persons.splice(index,1)
this.setState({persons:persons.splice(index,1)});
console.log(this.state)
console.log(persons)
}
this.state.persons.map((el,index)=>{
return(
<Person key={el.id} name={el.name} age={el.age} click={(index)=>{this.deletePersonsHandler(index)}}></Person>
)
}
}
as you see in the deletePersonsHandler()
I create a copy from the persons array and then I update the state immediately what happens is that the element that I click on doesn't get deleted instead I got stuck only with the first element but the rest gets deleted and the array only has two element as you see
no matter at which elemnt I clicked
before I click :
after I click on any element:
here's the state:
and here's the persons array that I newly created:
by the way I managed to solve the problem using this code:
deletePersonsHandler=(index)=>{
const persons= [...this.state.persons];
persons.splice(index,1)
this.setState({persons:persons});
}
but I wanna know what did I got wrong with the first try, why it didn't work the way I wanted, I'm still a beginner with react please be easy on me and thank you in advance. NOTE: I have another component which is the person component (I think it's not important to include here)
Upvotes: 0
Views: 48
Reputation: 1817
You should create another class besides App and you should add a constructor and there you should declare your state.
class MyComponent extends React.Component{
constructor() {
super();
this.state = {
persons: [
{ id: 'asfa1', name: 'Max', age: 28 },
{ id: 'vasdf1', name: 'Manu', age: 29 },
{ id: 'asdf11', name: 'Stephanie', age: 26 }
],
showPersons: false
}
}
}
And below the constructor you should declare your function:
deletePersonsHandler(index) {
const persons = [...this.state.persons];
persons.splice(index, 1);
this.setState({ persons });
}
But then you need to bind that method like:
constructor() {
...
this.deletePersonsHandler = this.deletePersonsHandler.bind(this);
}
And finally add the render function to your class like:
class MyComponent extends React.Component {
constructor() {
super();
this.state = {
persons: [
{ id: "asfa1", name: "Max", age: 28 },
{ id: "vasdf1", name: "Manu", age: 29 },
{ id: "asdf11", name: "Stephanie", age: 26 }
],
showPersons: false
};
this.deletePersonsHandler = this.deletePersonsHandler.bind(this);
}
deletePersonsHandler(index) {
const persons = [...this.state.persons];
persons.splice(index, 1);
this.setState({ persons });
}
render() {
return (
<div>
{this.state.persons.map((el, index) => {
return (
<Person
key={el.id}
name={el.name}
age={el.age}
click={() => {
this.deletePersonsHandler(index);
}}
/>
);
})}
</div>
);
}
}
You can check this working here
Upvotes: 0
Reputation: 407
In the first try, you just set the state with the new copy of array which contains only removed element.
this.setState({persons:persons.splice(index,1)});
// returns removed element
And then
const persons= [...this.state.persons];
persons.splice(index,1);
this.setState({persons:persons});
is setting elements after deleting the items in the array.
Look at the attached image
Upvotes: 1