Luis Monsalve
Luis Monsalve

Reputation: 160

Push and pop on react state

i have this react state in mi component

    this.state =
    {
        Preferences: []
    }

and i want to push only if the element not exists because i dont want the same repeated element, and i want to pop the element if is already exists this is the function what i use

    SelectPreference = Id =>
{
    
    if(!this.state.Preferences.includes(Id))
    {
        this.setState(state => 
        {
            const Preferences = state.Preferences.concat(Id);
       
            return {
                Preferences,
            };
        });

    }
    else
    {
        this.setState(state => 
        {
            const Preferences = state.Preferences.filter(Item => Item !== Id);
       
            return {
                Preferences,
            };
        });
    }
    console.log(this.state.Preferences);

}

the problem is when i push a object it says the array is empty and when i pop the element it says i have a element. i dont kwon how to do it

Upvotes: 0

Views: 2761

Answers (2)

Hassan Imam
Hassan Imam

Reputation: 22524

setState actions are asynchronous and are batched for performance gains. It will be pretty hard to immediately check the updated this.state.Preferences in the same function block.

Still if you need to check the updated value of the Preferences, you can provide a callback which will be executed immediately after change in state.

this.setState({ Preferences }, () => console.log(this.state))

Also, there is simpler version of your logic.

if(this.state.Preferences.includes(Id)) {
    this.setState({
        Preferences: this.state.Preferences.filter(id => id !== Id);
    });
} else {
    this.setState({
        Preferences: this.state.Preferences.concat(Id);
    });
}

Upvotes: 1

jean-smaug
jean-smaug

Reputation: 411

You can do as the following if you want your preferences to be uniq.

Based on your code, I understand that id is a string. Tell me if it's not the case.

For more info about Set and uniq value in array

if(!this.state.Preferences.includes(Id)) {
  this.setState(state => ({
    // Using a set will make sure your id is uniq
    Preferences: [...new Set([...state.Preferences, id])]
  }))
} 
else {
  this.setState(state => ({
    // You're code was good, I only change syntax
    Preferences: state.Preferences.filter(Item => Item !== Id)
  }))
}

Upvotes: 1

Related Questions