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 to learn React. I consider you a beginner and will explain the concepts from scratch.
Screenshot 1
Screenshot 2
You can get the complete source code along with the instructions on how to run it from the following repository on GitHub.
How to run (in brief)
You can run the application with “npm start”. The application will start at http://localhost:3000/
Note. Make sure you have npm installed.
Mainly, there are three React components in this application.
- Calculator
Contains the main control logic of the calculator and maintains the state.
- CalKeyBorad
The keyboard of the calculator
- DisplayPanel
Display the area of the calculator
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.
- State
- Events
- Render
State
Before we move further, we’ll have a look at what state is in React.js.
The 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.
state = {
calKeys:[
1,2,3,4,5,6,7,8,9,0 << represent the numeric keys of calc
],
displayValue:0, << always the current display value
prevVal:0, << used for calculation
signVal:'' << sign operator been pressed (+, -, *, or /)
}
So, the following is the state being used within the calculator. The 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.
- You can bind a function to the handler inside the constructor.
- You can use the arrow function.
What I’m using in this sample is the arrow function. But the following two are always identical.
this.handleClick = this.handleClick.bind(this)
is same as
handleClick = () => {}
Following are the events defined in the calculator.
handleKey = (val) => {
let displayVal = "" + this.state.displayValue;
displayVal += val;
this.setState({ displayValue: displayVal });
}
handleCKey = () => {
this.setState({ displayValue: 0 });
}
handleSignKey = (sign) => {
this.setState({ prevVal: this.state.displayValue, displayValue: 0, signVal: sign });
}
handleEqualsKey = () => {
let result = 0;
switch (this.state.signVal) {
case '+':
result = parseFloat(this.state.prevVal) + parseFloat(this.state.displayValue);
break;
case '-':
result = parseFloat(this.state.prevVal) - parseFloat(this.state.displayValue);
break;
case '*':
result = parseFloat(this.state.prevVal) * parseFloat(this.state.displayValue);
break;
case '/':
result = parseFloat(this.state.prevVal) / parseFloat(this.state.displayValue);
break;
default:
break;
}
this.setState({ displayValue: result });
}
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’ are.
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 the 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.
render() {
return (
<div>
<DisplayPanel val={this.state.displayValue}/>
<CalKeyBoard calKeys={this.state.calKeys}
onKey={this.handleKey}
onCKey={this.handleCKey}
onSignKey={this.handleSignKey}
onEqualsKey={this.handleEqualsKey}
/>
</div>
);
}
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 the following.
this.props.calKeys[0]
What we exactly doing here is accessing cal Keys 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 the state in the Calculator and code.
CalKeyBoard
render() {
return (
<div>
<button onClick={() => this.props.onKey(this.props.calKeys[0])} className="btn btn-danger btn-sm">{this.props.calKeys[0]}</button>
<button onClick={() => this.props.onKey(this.props.calKeys[1])} className="btn btn-danger btn-sm">{this.props.calKeys[1]}</button>
<button onClick={() => this.props.onKey(this.props.calKeys[2])} className="btn btn-danger btn-sm">{this.props.calKeys[2]}</button>
<button onClick={() => this.props.onSignKey('+')} className="btn btn-danger btn-sm">+</button>
<br/>
<button onClick={() => this.props.onKey(this.props.calKeys[3])} className="btn btn-danger btn-sm">{this.props.calKeys[3]}</button>
<button onClick={() => this.props.onKey(this.props.calKeys[4])} className="btn btn-danger btn-sm">{this.props.calKeys[4]}</button>
<button onClick={() => this.props.onKey(this.props.calKeys[5])} className="btn btn-danger btn-sm">{this.props.calKeys[5]}</button>
<button onClick={() => this.props.onSignKey('-')} className="btn btn-danger btn-sm">-</button>
<br/>
<button onClick={() => this.props.onKey(this.props.calKeys[6])} className="btn btn-danger btn-sm">{this.props.calKeys[6]}</button>
<button onClick={() => this.props.onKey(this.props.calKeys[7])} className="btn btn-danger btn-sm">{this.props.calKeys[7]}</button>
<button onClick={() => this.props.onKey(this.props.calKeys[8])} className="btn btn-danger btn-sm">{this.props.calKeys[8]}</button>
<button onClick={() => this.props.onSignKey('*')} className="btn btn-danger btn-sm">*</button>
<br/>
<button onClick={() => this.props.onKey(this.props.calKeys[9])} className="btn btn-danger btn-sm">{this.props.calKeys[9]}</button>
<button onClick={() => this.props.onKey(".")} className="btn btn-danger btn-sm">.</button>
<button onClick={() => this.props.onEqualsKey()} className="btn btn-danger btn-sm">=</button>
<button onClick={() => this.props.onSignKey('/')} className="btn btn-danger btn-sm">/</button>
<br/>
<button onClick={() => this.props.onCKey()} className="btn btn-dark btn-sm" style={{ width: "102px" }}>C</button>
</div>
);
}
DisplayPanel
render() {
return (
<div >
<span style={{ fontSize: 20 }} className={this.getBadgeClasses()}>{this.props.val}</span>
</div>
);
}
That’s it. Please do share your comments and suggestions.
Cheers!!