React showing previous state

Viewed 1225

This is my code inside a component.

this.state = {
            strength: 0,
            dexterity: 0,
            intelligence: 0,
            health: 0
        };

        this.increaseBasicAttrStrength = this.increaseBasicAttrStrength.bind(this);
        this.updateApp = this.updateApp.bind(this);

    }

    increaseBasicAttrStrength(event) {
        this.setState(prevState => ({
            strength: prevState.strength + 10,
            dexterity: prevState.dexterity,
            intelligence: prevState.intelligence,
            health: prevState.health
        }));
        this.updateApp();
    }

    updateApp() {
        console.log(this.state);
        this.props.basicAttrsHandler(this.state);
    }

Even though updateApp(...) called after increaseBasicAttrStrength(...), when i console the state it shows as below.

{strength: 0, dexterity: 0, intelligence: 0, health: 0}

state has not updated.

4 Answers

Not sure what updateApp is doing, but if you need to call it after your setState call is completed, you should place it inside a callback. SetState is asynchronous, so there's no guarantee those updates have occurred before updateApp is called. Using a callback ensures that whatever code inside does not run until the initial state update is complete:

increaseBasicAttrStrength(event) {
        this.setState(prevState => ({
            strength: prevState.strength + 10,
            dexterity: prevState.dexterity,
            intelligence: prevState.intelligence,
            health: prevState.health
        }), () => this.updateApp())
    }

setState is asynchronous. You can use callback method to get updated state.

increaseBasicAttrStrength(event) {
    this.setState(prevState => ({
        strength: prevState.strength + 10,
        dexterity: prevState.dexterity,
        intelligence: prevState.intelligence,
        health: prevState.health
    }, () => {console.log(this.state)}));

}

The reason why is because setState is assumed to be asynchronous. See this

Maybe this work, call update function after state updated in callback


    increaseBasicAttrStrength(event) {
        this.setState(prevState => ({
            strength: prevState.strength + 10,
            dexterity: prevState.dexterity,
            intelligence: prevState.intelligence,
            health: prevState.health
        }),()=>{
        this.updateApp(); //add this function in callback
       });

    }
Related