ReactJS | Calculator App ( Adding Functionality )

In our previous article, we had built the structure of our UI, but we haven’t added styles to it neither we have added any functionality. You can see that if you click the buttons for now then nothing is getting typed on the screen. So, in this article, we will try to make our Calculator app fully functional. Once our app becomes functional, we will add CSS to style our App.

So, let’s begin. The very first functionality we will add is for the click event of the buttons. To handle the click events, we will create a new function named handleClick and will add this function to our Calculator component class. But, the next thing to observe is that the buttons from “0-9” and operators like “+,-,*,/” will have different roles and other buttons like “=”,”Clear” and “Delete” have different roles. So, what we can do is inside the handleClick function we will use a switch..case statement to perform different operations on clicking different buttons.

But before doing this, let us see that what states do we need? We need to create two states for our Calculator application and we will update these two states according to the user inputs. The two states that we need are:

  • question: Initially this state will be initialized with an empty string. This state will be used to store the user input.
  • answer: Initially this state will be initialized with an empty string. This state will be used to store the result of the evaluation of user input stored in the state question.

Add the below code at the top of the class Calculator in the file calculator.js. This code will create the required states for us:

filter_none

edit
close

play_arrow

link
brightness_4
code

constructor() {
    super();
  
    // set our default state
    this.state = {
      question: '',
      answer: ''
    }
  
    // Bind our handleClick method (sets 'this' explicitly
    // to refer to this componenent) We did this because 'this'
    // would refer to the source of the click events
    this.handleClick = this.handleClick.bind(this);
  }

chevron_right


Since, now we have created our states to store the user input and aswers. Let’s just complete our handleClick function to update these states according to different button clicks.

Add the below function to the class Calculator in the calculator.js file:

filter_none

edit
close

play_arrow

link
brightness_4
code

// our method to handle all click events from our buttons
handleClick(event){
 
  // get the value from the target element (button)
  const value = event.target.value;
 
  switch (value) {
    case '=': {
 
      // if it's an equal sign, use the eval module
      // to evaluate the question ,convert the answer
      // (in number) to String
      if (this.state.question!=='')
      {
          var ans='';
            try
              {
                  ans = eval(this.state.question);
              }
              catch(err)
              {
                  this.setState({answer: "Math Error"});
              }
              if (ans===undefined)
                  this.setState({answer: "Math Error"});
 
              // update answer in our state.
              else
                  this.setState({ answer: ans , question: ''});
              break;
          }
    }
    case 'Clear': {
 
      // if it's the Clears sign, just clean our 
      // question and answer in the state
      this.setState({ question: '', answer: '' });
      break;
    }
 
    case 'Delete': {
      var str = this.state.question;
        str = str.substr(0,str.length-1);
        this.setState({question: str});
        break;
    }
 
  default: {
 
      // for every other commmand, update the answer in the state
      this.setState({ question: this.state.question += value})
      break;
    }
  }
}

chevron_right


Now, we are completed with adding all functionalities but still, if we click the buttons of our Calculator app in the browser, nothing will happen. The reason behind this is we have not linked our handleClick function with the button’s onClick attribute in our Button component in the button.js file. To do so, we will pass the handleClick function as props to the Button component and assign this function to the button’s onClick event in Button component.

We will add the below line everywhere in our Calculator component from where we are calling our Button Component to pass the handleClick function as props to the Button component:

handleClick = {this.handleClick}

After adding this, we will go to the button.js file, and add the below attribute to the input field:

onClick = {props.handleClick}

Now everything is set-up. Our states are getting updated on Click of our buttons. But wait, we still can’t see any change in our app in browser. Let’s recall what went wrong. The problem is we have not passed the states to the OutputScreen component. So our OutputScreen component has nothing to render on screen. So, let’s update our OutputScreen and OutputScreenRow components to accept props and pass the question and answer states from Calculator component to the OutputScreen component as props.

After doing this, pass the props from inside of OutputScreen component to OutputScreenRow components as values to display them in the input fields.

Below is our final outputscreen.js file:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Import React (Mandatory Step).
import React from 'react';
  
// Import Output Screen Row.
import OutputScreenRow from './outputScreenRow.js';
  
// Functional Component.
// Use to hold two Screen Rows.
const OutputScreen = (props) => {
  return (
    <div className="screen">
      <OutputScreenRow value = {props.question}/>
      <OutputScreenRow value = {props.answer}/>
    </div>
  )
}
  
// Export Output Screen.
export default OutputScreen;

chevron_right


Below is our final outputscreenrow.js file:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Import React (Mandatory Step).
import React from 'react';
  
// Functional Component.
// Used to show Question/Answer.
const OutputScreenRow = (props) => {
  return (
    <div className="screen-row">
      <input type="text" readOnly value = {props.value}/>
    </div>
  )
}
  
// Export Output Screen Row.
export default OutputScreenRow;

chevron_right


You can see in the below image that our Calculator App is working fine and has the same functionality as that of what we saw in our first article. In our next article, we will add styles to this and will try to sum up what we have done so far to build this App.



My Personal Notes arrow_drop_up

Senior Technical Content Engineer | GeeksforGeeks

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.