DEV Community

Cover image for How To Create A Simple Calculator Web App Using React.JS
Georgi Georgiev
Georgi Georgiev

Posted on • Edited on

How To Create A Simple Calculator Web App Using React.JS

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!

Final Project - Calculator app

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

  1. Calculator — main component containing all the rest
  2. Display — contains the display area on the top
  3. Button — represents each button on the keypad
  4. Keypad — in this component we will put all the buttons

Components represented as boxes

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;
Enter fullscreen mode Exit fullscreen mode
.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;
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode
.Display {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    background: #2b293d;
    height: 20%;
    color: #80c9c9;
    font-size: 24px;
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode
.Keypad {
    display: flex;
    flex-wrap: wrap;
    flex-direction: column;
    height: 80%;
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode
body {
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.Calculator {
    width: 400px;
    height: 300px;
    position: relative;
    margin: 25px;
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
metak profile image
Dimitar Yanev
Collapse
 
gjorgiev profile image
Georgi Georgiev

math.js would be a better solution.