Amine El were
Amine El were

Reputation: 855

how to update the state properly in react

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 :

enter image description here

after I click on any element:

enter image description here

here's the state:

enter image description here

and here's the persons array that I newly created:

enter image description here

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

Answers (2)

MaCadiz
MaCadiz

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

Nuwan.Niroshana
Nuwan.Niroshana

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

enter image description here

Upvotes: 1

Related Questions