A calculator is among the top 5 projects a beginner in web development should make to test his programming skills. It is used to test the basics of any programming language a web developer should have for moving forward.
In this blog, we will make a simple calculator with all its functionalities but with the help of React Hooks and simple js functions.
Index
- Getting Started
- Creating our React app
- Working on the UI part of the app
- Creating buttons dynamically
- Adding functionality with hooks
- Wrapping Up
Let’s begin
Getting Started
Making a calculator in React tests some basic skills like hooks and creating and using dynamic data to get the value.
We will be using Bootstrap as CDN for our app for styling purposes, but you can also go with other css frameworks or even use Vanilla CSS.
We hope that after this tutorial, you will be well versed with some basic concepts of React and Hooks and mostly use dynamic data to reduce the number of lines of codes.
Creating our React App
It’s easy to create a React App, go to your working directory in any of your preferred IDE’s and enter the following command in the terminal
If you are unsure how to properly set up a create-react-app project you can refer to the official guide here at create-react-app-dev.‌‌
npx create-react-app calculator-in-react
After the setup, run npm start in the same terminal to start the localhost:3000 where our React will be hosted and we can see all our changes there.
Working on the UI part of our App
There are two sections in a calculator – one where all the values and operators are shown, and the result after using operators that will be an input field, and the other contains all the values and operators as buttons. Our calculator will also have two sections like the original one.
import React from "react";
const App = () => {
return (
<>
<div className="container-fluid">
<div className="row mt-5 pt-5" id="main">
<dic className="col-md-12 col-sm-12 mt-3 text-center fs-1 mb-3 fw-bolder">
Calculator
</dic>
<div className="col-md-4 col-sm-3"></div>
<div className="col-md-4 col-sm-6 p-3 bg-dark">
<div id="screen" className="col-12 bg-dark text-light text-end p-3">
<input
placeholder="0"
className="fs-1 fw-bold mx-3 col-12 bg-dark text-light border-0 text-end bg"
/>
</div>
<input
type="button"
className="col-md-3 col-sm-3 text-center fw-bold"
value="C"
/>
<input
type="button"
className="col-md-3 col-sm-3 text-center fw-bold"
value="del"
/>
<div className="w-100 py-2"></div>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="1"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="2"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="3"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="/"
/>
<div className="w-100 py-2"></div>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="4"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="5"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="6"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="-"
/>
<div className="w-100 py-2"></div>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="7"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="8"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="9"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="+"
/>
<div className="w-100 py-2"></div>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="0"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="."
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="*"
/>
<input
type="button"
className="col-md-2 col-sm-2 text-center fw-bold"
value="="
/>
</div>
</div>
</div>
</>
);
};
export default App;
CSS has not been discussed in this blog so that you can work on your CSS for styling and making it responsive, but most of the styling here has been done by Bootstrap.
Creating Buttons Dynamically
The above code contains too many lines of the same code, the only difference is in the value attribute. Thus, we will be creating a separate component for them named Data.js
that is as follows –
const Data = [
{
symbol: "/",
className: "input btn btn-secondary text-dark fw-bold fs-5 px-2 ms-1 mt-2",
},
{
symbol: "%",
className: "input btn btn-warning text-dark fs-5 ms-1 mt-2",
},
{
symbol: "7",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: "8",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: "9",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: "*",
className: "input btn btn-warning text-dark fs-5 p2-3 ms-1 mt-2",
},
{
symbol: "4",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: "5",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: "6",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: "-",
className: "input btn btn-warning text-dark fs-5 p2-3 ms-1 mt-2",
},
{
symbol: "1",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: "2",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: "3",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: "+",
className: "input btn btn-warning text-dark fs-5 p2-3 ms-1 mt-2",
},
{
symbol: "+/-",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: "0",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
{
symbol: ".",
className: "input btn btn-dark text-light fs-5 px-2 ms-1 mt-2",
},
];
export default Data;
This component does not have access to every value of the calculator like ‘=’, ‘C’, and ‘Del’, this is due to their functionalities which are different from the rest of the buttons.
We have to import the Data to start using these values
import React from "react";
import Data from "./Data";
const App = () => {
return (
<>
<div className="container-fluid">
<div className="row" id="main">
<dic class="col-md-12 col-sm-12 my-5 text-center fs-1 mb-3 fw-bolder">Calculator</dic>
<div className="col-md-4 col-sm-3"></div>
<div className="col-md-4 col-sm-6 p-3 bg-dark">
<div id="screen" className="col-12 bg-dark text-light text-end p-3">
<input
placeholder="0"
className="fs-1 fw-bold mx-3 col-12 bg-dark text-light border-0 text-end bg"
/>
</div>
<input
type="button"
value="Del"
className="btn btn-secondary text-dark fw-bold fs-5 px-3 ms-1 mt-2"
/>
<input
type="button"
value="C"
className="btn btn-secondary text-dark fw-bold fs-5 px-3 ms-1 mt-2"
/>
{Data.map((Val) => {
// destructuring the values of Val to make it easier to write code.
const { symbol, className } = Val;
return (
<>
<input
type="button"
value={symbol}
className={`${className}`} // adding bootstrap classes dynamically
/>
</>
);
})}
<input
type="button"
value="="
className="btn btn-warning text-dark fs-5 px-3 ms-1 mt-2"
/>
</div>
</div>
</div>
</>
);
};
export default App;
Adding Functionality with Hooks
We are done with the UI part of our app, and now its time to add some functionalities to make it a proper calculator which can perform some basic calculations like – add, subtract, divide and multiply, and we will achieve this functionality with the help of some JavaScript functions and useState hook.
const [result, setResult] = useState("");
The variable result will become the value for the value attribute of our input where all the values will be shown, and the other variable is responsible for managing our state and displaying the changes made if any.
Using the onClick() event handler, we will give the buttons their respective functionalities.
import React, { useState } from "react";
import Data from "./Data";
const App = () => {
const [result, setResult] = useState("");
return (
<>
<div className="container-fluid">
<div className="row" id="main">
<dic class="col-md-12 col-sm-12 my-5 text-center fs-1 mb-3 fw-bolder">Calculator</dic>
<div className="col-md-4 col-sm-3"></div>
<div className="col-md-4 col-sm-6 p-3 bg-dark">
<div id="screen" className="col-12 bg-dark text-light text-end p-3">
<input
placeholder="0"
value={result}
className="fs-1 fw-bold mx-3 col-12 bg-dark text-light border-0 text-end bg"
/>
</div>
<input
type="button"
value="Del"
className="btn btn-secondary text-dark fw-bold fs-5 px-3 ms-1 mt-2"
onClick={(e) => setResult(result.slice(0, -1))}
/>
<input
type="button"
value="Clear"
className="btn btn-secondary text-dark fw-bold fs-5 px-3 ms-1 mt-2"
onClick={() => setResult("")}
/>
{Data.map((Val) => {
const { symbol, className } = Val;
return (
<>
<input
type="button"
value={symbol}
className={`${className}`}
onClick={(e) => setResult(result.concat(e.target.value))}
/>
</>
);
})}
<input
type="button"
value="="
className="btn btn-warning text-dark fs-5 px-3 ms-1 mt-2"
onClick={() => setResult(eval(result).toString())}
/>
</div>
</div>
</div>
</>
);
};
export default App;
Wrapping Up
Now that our buttons have their respective functionalities, our calculator is complete and is ready to use. See the video for the final result.
You can also visit the GitHub Repo of this project. And don’t forget to contact me if you have any doubts regarding this blog or code.
I constantly spent my half an hour to read this blog’s posts all the time along with a mug of coffee.
Thank you