Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React on render shows previous state value

Tags:

reactjs

render

I'm a beginner for ReactJS, just started learning and started writing code for guessing numbers but the guess count shows different values. {this.state.attempts} holds the no. of attempts it took the user to find the answer to show the correct value. But {this.state.result} shows the result on each click but if user finds the answer it shows the previous state. I'm wondering how this happens. Is that because it's not under render()?

import React, { Component } from 'react';

export default class NoLifeCycComps extends Component {
    constructor(props) {
        super(props);
        this.state = this.getInitialState();
        this.checkValue = this.checkValue.bind(this);
        this.updateInput = this.updateInput.bind(this);
    }

    randNum(){
        return Math.floor((Math.random() * 100) + 1);
    }

    getInitialState(){
        return {
            num: this.randNum(),
            inputValue: '',
            attempts: 0,
            result: '',
            reset : false
        }
    }

    reset() {
        this.setState(this.getInitialState());
    }

    checkValue() {
        this.setState((prevState) => {
            return { attempts: prevState.attempts + 1 }
        });
        if (this.state.inputValue > this.state.num) {
            this.state.result = "higher";
        } else if (this.state.inputValue < this.state.num) {
            this.state.result = "lesser";
        } else if (this.state.inputValue == this.state.num) {
            this.state.result = "you found it on " + this.state.attempts + "attempt(s)";
            this.state.reset = true;
        }
    }


    updateInput(e) {
        this.setState({ inputValue: e.target.value })
    }

    render() {

        return ( 
            <div className = "numberGuess">
                <h3> Guess the number </h3>
                <input type = "text" value = { this.state.inputValue } onChange = { this.updateInput }/>

                {this.state.reset  ? <button onClick = { () => this.reset() }> start again! </button> : <button onClick = { () => this.checkValue() }> click </button>}
                No.of Attempts took: { this.state.attempts } <br/>
                <span> { this.state.result } </span>
            </div>
        );
    }
}
like image 806
Karthikkumar Avatar asked Jun 22 '18 09:06

Karthikkumar


1 Answers

setState is a async function. Next statement of setState may not have updated state value. Also I found mutation state update in your code. Please avoid mutation update. You should update all state using setState

Example

  checkValue() {
    let {
      attempts,
      inputValue,
      num,
      result,
      reset
    } = this.state;

    attempts++;

    if (inputValue > num) {
      result = "higher";
    } else if (inputValue < num) {
      result = "lesser";
    } else if (inputValue == num) {
      result = "you found it on " + attempts + "attempt(s)";
      reset = true;
    }

    this.setState({
      attempts,
      result,
      reset
    });
  }

In this example we storing existing state value in variables and doing operation on that. At the end of calculation we are updating state once.

like image 163
Kishan Mundha Avatar answered Nov 05 '22 19:11

Kishan Mundha