ReactJS: Wrong execution order on calculator

Hello, I’ve been working on the Javascript calculator project and have been doing it in React because it seemed to be relatively straightforward to do in react, however when I assign something using setState then call a function, the called function executes before the setState does, even though the function call is under the setState. More specifically, I am trying to assign numbers based on the button pressed then concat it to a string of previous inputs before converting to a float to display, but the number it adds is always the number of the button i pressed previously, not the button i pressed the current time. I only have 0 and 1 bound for now for proof of concept, but youll see if you press either button it gives you the placeholder value rather than the number assigned to the button you press. Is there any way to make the initial setState occur before the function call?

Codepen: https://codepen.io/AugustTGuenther/pen/ExPppvy

Bumping for others to view

Hey there,

setState is an async function.

If you want to run a function after a setState call, you can read about it here:

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use […] a setState callback ( setState(updater, callback) ), either of which are guaranteed to fire after the update has been applied.

Keep us posted if you can use this information to update your code.

2 Likes

I tried both using componentDidMount as well as a setState callback but both seem to work the same as what I had before. Currently have it not using DidMount, just a setState callback and I had the exact same issue with both.

Because I don’t know what your specific problem is, I can’t test it.

But my best guess:

You are currently using this code:

    this.setState({
      pushed: '0'
    }, this.handleNums()) 

Try to use it like this:

    this.setState({
      pushed: '0'
    }, () => this.handleNums()) 

Aha, that solved my issue perfectly. Thank you so much for the help :smiley:

Awesome,

glad you did it,
you’re welcome!

I got an idea for you:

  • currently you have a lot of duplicate code for handling the button, e.g. zeroPress, onePress etc. You can refactor them into one function that depends on a parameter.

Example:

Before:

  zeroPress(){
    this.setState({
      pushed: '0'
    }, () => this.handleNums()) 
  }

After:

  handlePress(numberPressed){
    this.setState({
      pushed: numberPressed
    }, () => this.handleNums()) 
  }

You can run it by using onClick={() => this.handlePress(0)} for the button 0.

Let me know if you like this idea.

1 Like

Dude! You are my ReactJS saviour! I was hoping I could do it without making a bunch of functions but couldn’t think of how because I didn’t quite understand arrow notation, but the 2 tips you’ve given me has at least let me understand the very simple use for a nameless function. Gonna trim it down later as well as trim down my operator handling syntax using the same premise :+1::+1: glad you told me this before I did the same thing for those.

Thank you, I’m very flattered!

Let me know when you need some ideas how to handle stuff!

So I got a few more kinks worked out but now im realizing a huge problem, I am having a lot of trouble integrating the minus button working as a negative sign in specific scenarios. I tried setting it up so if another operator was in use it would make the input negative, however it blocked me out of using the minus operator any time after the first calculation if i wanted to do a chain. Also, it seems Javascript automatically takes 5.0 and gets rid of the decimal which I dont want it to do for a test case. Any ideas how to tackle these two problems?

First, I would separate both problems:

  1. the “minus sign”-issue
  2. the “gets rid of decimals”-issue

Let’s have a look at #1:

  • can you find examples for the problem?
  • can you describe the exact problem?

An example is: If i do 5 * -9, it works perfectly no problem. If i do 5 * 9 - 4, the -4 will end up multiplying as -4 because i currently have it so it cannot change operators to subtract if this.state.operator != “placeholder”. I think I can put a line in where it would replace operator with placeholder after each subsequent calculation, but I’m having trouble thinking of where I could place it such that the previous operation would not be affected.

Hey there,

did you make some progress on that?

If you would have to explain to a kid how to calculate 5 * 9 - 4 by hand, how would you do it?

Been getting caught up in family matters so havent been working on it (starting back up tomorrow) but I think im going to re-write the program and try to implement it in the program while coding rather than going back and changing a bunch of stuff. I’ve learned a lot about general coding practices by your examples as well as my own thinking through of things so I think its gonna be easier that way.

1 Like

Glad it helped :slight_smile:

Keep us posted!