A Simple Calculator In React.js

In this article, we will learn to build a simple calculator written in React.js. I just wrote this for fun.

Introduction

 
This is a simple calculator written in React.js. I just wrote this for fun. You may need some basic understanding of React in order to use the sample and having said that, I will not explain the code line by line but I will provide you with the guidelines below. In fact, this could also be an entry point for you towards learning React. I consider you as a beginner and will explain the concepts from scratch.

Screenshot #1

A Simple Calculator In React.js 
 
Screenshot #2
 
A Simple Calculator In React.js 

You can get the complete source code along with the instructions of how to run it from the following repository on GitHub.

How to run (in brief)

You can run the application with “npm start”. Application will start in http://localhost:3000/

Note: Make sure you have npm installed.

Mainly, there are three React components in this application.

  • Calculator
    Contains main control logic of the calculator and maintains the state.

  • CalKeyBorad
    Keyboard of the calculator

  • DisplayPanel
    Display area of the calculator
A Simple Calculator In React.js 

CalKeyBorad and DisplayPanel, both are fairly simple components.

So, let’s first take a look at the Calculator component. There are three focus areas in it.

  1. State
  2. Events
  3. Render

State

Before we move further, we’ll have a look at what stateis in React.js.

State is the place where the data comes from. We should always try to make our state as simple as possible and minimize the number of stateful components. If we have, for example, ten components that need data from the state, we should create one container component that will keep the state for all of them.

Now, back to our calculator module.

  1. state = {  
  2.    calKeys:[  
  3.        1,2,3,4,5,6,7,8,9,0 << represent the numeric keys of calc  
  4.    ],  
  5.    displayValue:0, << always the current display value  
  6.    prevVal:0, << used for calculation  
  7.    signVal:'' << sign operator been pressed (+, - , * or /)  
  8. }  

So, following is the state being used within the calculator. Calculator holds all the state information for components. This state is shared among the other components as required, via props.

And following are the events used for keys.

Events

You can pass functions as the event handlers in React.js.

There are two ways of doing this.

  1. You can bind a function to the handler inside the constructor.
  2. You can use the arrow function.

What I’m using in this sample is the arrow function. But the following two are always identical.

  1. this.handleClick = this.handleClick.bind(this)   
  2. is same as   
  3. handleClick = ()=>{}  

Following are the events defined in the calculator.

  1. handleKey = (val) => {  
  2.    let displayVal = "" + this.state.displayValue;  
  3.    displayVal += val;  
  4.    this.setState({ displayValue:displayVal});  
  5. }  
  6.   
  7. handleCKey =() => {  
  8.    this.setState({displayValue:0})  
  9. }  
  10.   
  11. handleSignKey =(sign) =>{  
  12.    this.setState({prevVal: this.state.displayValue, displayValue:0, signVal:sign});  
  13. }  
  14.   
  15. handleEqualsKey= () =>{  
  16.    let result = 0;  
  17.    switch (this.state.signVal){  
  18.        case '+':  
  19.            result = parseFloat(this.state.prevVal)+ parseFloat(this.state.displayValue);  
  20.            break;  
  21.        case '-':  
  22.            result = parseFloat(this.state.prevVal)- parseFloat(this.state.displayValue);  
  23.            break;  
  24.        case '*':  
  25.            result = parseFloat(this.state.prevVal)* parseFloat(this.state.displayValue);  
  26.            break;  
  27.        case '/':  
  28.            result = parseFloat(this.state.prevVal)/parseFloat(this.state.displayValue);  
  29.            break;  
  30.        default:  
  31.            break;  
  32.    }  
  33.    this.setState({displayValue: result})  
  34. }  

Read more about React.js events.

Render

And finally, we reach the rendering part which renders individual components of CalKeyBoard and DisplayPanel.

Before we move further, we need to look into what ‘props’ is.

Props is the same as a state, but it is used for sharing the code between components. The main difference between state and props is that props are immutable. That means container component should always define the state that can be updated and changed, while the child components should only pass data from the state using props.

  1. render() {  
  2.    return (  
  3.        <div>  
  4.        <DisplayPanel val={this.state.displayValue}/>  
  5.        <CalKeyBoard calKeys={this.state.calKeys}  
  6.                     onKey={this.handleKey}  
  7.                     onCKey={this.handleCKey}  
  8.                     onSignKey={this.handleSignKey}  
  9.                     onEqualsKey={this.handleEqualsKey}  
  10.        />  
  11.        </div>  
  12.    );  
  13. }  

In the render method, you can see

calKeys={this.state.calKeys}

What exactly we are doing here is that we pass the state of ‘calKeys’ via ‘calKeys’, so the child component accesses those via props like following.

this.props.calKeys[0]

What we exactly doing here is accessing calKeys via props and getting the first element of the array.

As I told you earlier, CalKeyBoard and DisplayPanel are simple components. We have to use props to get access to state in Calculator and code.

CalKeyBoard 

  1. render() {  
  2.    return (  
  3.        <div>  
  4.            <button onClick={()=>this.props.onKey(this.props.calKeys[0])}  
  5.                    className="btn btn-danger btn-sm" >{this.props.calKeys[0]}</button>  
  6.           <button onClick={() => this.props.onKey(this.props.calKeys[1])}  
  7.                    className="btn btn-danger btn-sm" >{this.props.calKeys[1]}</button>  
  8.            <button onClick={() => this.props.onKey(this.props.calKeys[2])}  
  9.                    className="btn btn-danger btn-sm" >{this.props.calKeys[2]}</button>  
  10.            <button onClick={() => this.props.onSignKey('+')}  
  11.                    className="btn btn-danger btn-sm" >+</button>  
  12.            <br/>  
  13.            <button onClick={() => this.props.onKey(this.props.calKeys[3])}  
  14.                    className="btn btn-danger btn-sm" >{this.props.calKeys[3]}</button>  
  15.            <button onClick={() => this.props.onKey(this.props.calKeys[4])}  
  16.                    className="btn btn-danger btn-sm" >{this.props.calKeys[4]}</button>  
  17.            <button onClick={() => this.props.onKey(this.props.calKeys[5])}  
  18.                    className="btn btn-danger btn-sm" >{this.props.calKeys[5]}</button>  
  19.            <button onClick={() => this.props.onSignKey('-')}  
  20.                    className="btn btn-danger btn-sm" >-</button>  
  21.            <br/>  
  22.            <button onClick={() => this.props.onKey(this.props.calKeys[6])}  
  23.                    className="btn btn-danger btn-sm" >{this.props.calKeys[6]}</button>  
  24.            <button onClick={() => this.props.onKey(this.props.calKeys[7])}  
  25.                    className="btn btn-danger btn-sm" >{this.props.calKeys[7]}</button>  
  26.            <button onClick={() => this.props.onKey(this.props.calKeys[8])}  
  27.                    className="btn btn-danger btn-sm" >{this.props.calKeys[8]}</button>  
  28.            <button onClick={() => this.props.onSignKey('*')}  
  29.                    className="btn btn-danger btn-sm" >*</button>  
  30.            <br/>  
  31.            <button onClick={() => this.props.onKey(this.props.calKeys[9])}  
  32.                    className="btn btn-danger btn-sm" >{this.props.calKeys[9]}</button>  
  33.            <button onClick={() => this.props.onKey(".")}  
  34.                    className="btn btn-danger btn-sm" >.</button>  
  35.            <button onClick={() => this.props.onEqualsKey()}  
  36.                    className="btn btn-danger btn-sm" >=</button>  
  37.            <button onClick={() => this.props.onSignKey('/')}  
  38.                    className="btn btn-danger btn-sm" >/</button>  
  39.            <br/>  
  40.            <button onClick={() => this.props.onCKey()}  
  41.                    className="btn btn-dark btn-sm" style={{width:"102px"}}>C</button>  
  42.   
  43.        </div>  
  44.    );  
  45. }  

DisplayPanel

  1. render() {  
  2.    return (  
  3.        <div >  
  4.            <span style={{ fontSize:20}} className={this.getBadgeClasses()}>{this.props.val}</span>  
  5.        </div>  
  6.    );  
  7. }  

That’s it. Please do share your comment and suggestions.

Cheers!!