In this article, I am going to explain how did I create a simple calculator using React. There might be bugs, but this is only for learning purposes and training the basic concepts of React.
Recently I went through the main concepts of React library from Facebook, and I was amazed by the simplicity and clearness of React.
Let’s dive into the project!
Step 1: Break The UI Into Components
First, we need to determine what is Component in the case. In this example we can see that Button could be a separate component, then we will have to put all the buttons together, so we will have the Keypad component. Next, we see on the top we’ll need a place to show the expression and result, that will be the Display component. In the end, we need to put it all together, so we named the last component as Calculator, you can name it whatever you want, that could be the App component also.
Components
- Calculator — main component containing all the rest
- Display — contains the display area on the top
- Button — represents each button on the keypad
- Keypad — in this component we will put all the buttons
Step 2: Build A Static Version in React
Start with the easiest possible solution without implementing the interactivity and state. We only need to write the components with their basic render functions, that way it is easier to work.
I’ve decided to start with the Button component because there is no other component inside it, so I don’t need to deal with composition even before implementing the parent component, you will see what I am talking about when we write the Keypad component.
import React, {Component} from 'react';
import "./Button.css";
class Button extends Component {
render(){
return(
<div
className="Button"
onClick={this.props.onClick}
data-size={this.props.size}
data-value={this.props.value}>
{this.props.label}
</div>
);
}
}
export default Button;
.Button {
background: #cad2c5;
display: flex;
border: 1px solid rgba(0,0,0,0.05);
box-sizing: border-box;
align-items: center;
justify-content: center;
width: 25%;
font-size: 24px;
color: rgba(0, 0, 0, 0.5);
height: 20%;
min-width: 25%;
}
.Button[data-size="2"] {
height: 40%;
}
.Button[data-value="null"] {
pointer-events: none;
}
.Button:hover {
background: #d7ddd3;
cursor: default;
}
Then we write the Display component
import React, {Component} from 'react';
import "./Display.css";
class Display extends Component {
render(){
return(
<div className="Display">
{this.props.data}
</div>
);
}
}
export default Display;
.Display {
display: flex;
justify-content: flex-end;
align-items: center;
background: #2b293d;
height: 20%;
color: #80c9c9;
font-size: 24px;
}
The next component is Keypad, this one is using {this.props.children} as a way to render anything which will be written inside it, this could be any other component.
import React, {Component} from 'react';
import "./Keypad.css";
class Keypad extends Component {
render(){
return(
<div className="Keypad">
{/* We are using composition instead of inheritance.
read more: https://reactjs.org/docs/composition-vs-inheritance.html */}
{this.props.children}
</div>
);
}
}
export default Keypad;
.Keypad {
display: flex;
flex-wrap: wrap;
flex-direction: column;
height: 80%;
}
Finally, we will write a basic version of the Calculator component, here we are only implementing the render() function to have the structure of the app, then we will think about the state and where should it live.
import React, {Component} from 'react';
import Button from './Button';
import Keypad from './Keypad';
import './Calculator.css';
import Display from './Display';
class Calculator extends Component {
render(){
return(
<div className="Calculator">
<Display data={this.state.data}/>
<Keypad>
<Button label="C" value="clear" />
<Button label="7" value="7" />
<Button label="4" value="4" />
<Button label="1" value="1" />
<Button label="0" value="0" />
<Button label="/" value="/" />
<Button label="8" value="8" />
<Button label="5" value="5" />
<Button label="2" value="2" />
<Button label="." value="." />
<Button label="x" value="*" />
<Button label="9" value="9" />
<Button label="6" value="6" />
<Button label="3" value="3" />
<Button label="" value="null" />
<Button label="-" value="-" />
<Button label="+" size="2" value="+" />
<Button label="=" size="2" value="equal" />
</Keypad>
</div>
);
}
}
export default Calculator;
body {
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.Calculator {
width: 400px;
height: 300px;
position: relative;
margin: 25px;
}
You can also see how we used the Keypad component in composition with the Button component.
Step 3: Identify and Implement The State
First, we ask ourselves, which components will be sharing a state? In our case, that is the Button and the Display components, and they are both living in the Calculator component, so that’s where we will implement the state.
As a state, we are going to need only one parameter, and that is the data or expression which is shown on the display by pressing the buttons.
Here is the full Calculator component implemented with state and needed functions to manipulate the state.
import React, {Component} from 'react';
import Button from './Button';
import './Calculator.css';
import Display from './Display';
import Keypad from './Keypad';
class Calculator extends Component {
constructor() {
super();
this.state = { data: ''}
}
calculate = () => {
try {
const result = eval(this.state.data);
this.setState({data: result});
} catch (e) {
this.setState({data: 'error'})
}
}
handleClick = e => {
const value = e.target.getAttribute('data-value');
switch(value) {
case 'clear':
this.setState({ data: ''});
break;
case 'equal':
this.calculate();
break;
default:
this.setState({ data: this.state.data + value});
}
}
render(){
return(
<div className="Calculator">
<Display data={this.state.data}/>
<Keypad>
<Button onClick={this.handleClick} label="C" value="clear" />
<Button onClick={this.handleClick} label="7" value="7" />
<Button onClick={this.handleClick} label="4" value="4" />
<Button onClick={this.handleClick} label="1" value="1" />
<Button onClick={this.handleClick} label="0" value="0" />
<Button onClick={this.handleClick} label="/" value="/" />
<Button onClick={this.handleClick} label="8" value="8" />
<Button onClick={this.handleClick} label="5" value="5" />
<Button onClick={this.handleClick} label="2" value="2" />
<Button onClick={this.handleClick} label="." value="." />
<Button onClick={this.handleClick} label="x" value="*" />
<Button onClick={this.handleClick} label="9" value="9" />
<Button onClick={this.handleClick} label="6" value="6" />
<Button onClick={this.handleClick} label="3" value="3" />
<Button onClick={this.handleClick} label="" value="null" />
<Button onClick={this.handleClick} label="-" value="-" />
<Button onClick={this.handleClick} label="+" size="2" value="+" />
<Button onClick={this.handleClick} label="=" size="2" value="equal" />
</Keypad>
</div>
);
}
}
export default Calculator;
This is a very simple example of React app, but we used most of the main concepts, like the composition of components, passing parameters from parent to child component, keeping and modifying the state, etc…
I hope I did explain the process, you can also check the full source code on GitHub.
If you have any suggestions or questions please let me know in the comments.
Thanks for reading!
Top comments (2)
Never use eval.
developer.mozilla.org/en-US/docs/W...!
math.js would be a better solution.