DEV Community

loading...
Cover image for React Calculator App

React Calculator App

uzomezu profile image Kevin Mezu ・3 min read

Here's a fun project utilizing react-app basics to create a functional calculator.

Please Check Part 1 for the wireframes and styling used in this project.

If you'd like navigate to my github, clone the repo, and code along with my tutorial.

Click Here for Repo: dieter-rams-react-calc

Okay let's begin!

Step 1. Calculator Buttons

First we need to understand our application in components. The user has three options for buttons:

  • numbers and operators
  • Equals
  • Clear

The button components will use the following syntax to represent a Button within the calculator.

import React, {Component} from 'react';

class Button extends Component {
    render() {
        return(
            <p className="col-auto">
               <button className="button" 
onClick={()=>this.props.handleClick(this.props.children)}>
                    {this.props.children}
               </button>
            </p>
        )
    }
}

export default Button
Enter fullscreen mode Exit fullscreen mode

Notice how this.props.children accounts for the child element with the exported component. This way we can simply place our number or operators inside the JSX. The handleClick() allows for a handleClick function in exported component.

Once you import your JSX document should look this way.

<div className="card-body buttons-grid">
                <div className="row">
                    <Button handleClick={clickButton}></Button>
                   <Button handleClick={clickButton}>7</Button>
                    <Button handleClick={clickButton}>8</Button>
                   <Button handleClick={clickButton}>9</Button>  
                   <Button handleClick={operation_Func}>/</Button>
                </div>
                <div className="row">
                  <Button handleClick={clickButton}></Button>
                    <Button handleClick={clickButton}>4</Button>
                    <Button handleClick={clickButton}>5</Button>
                    <Button handleClick={clickButton}>6</Button>
                    <Button handleClick={operation_Func}>*</Button>
                </div>
                <div className="row">
                   <Button handleClick={clickButton}>%</Button>
                   <Button handleClick={clickButton}>3</Button>
                   <Button handleClick={clickButton}>2</Button>
                   <Button handleClick={clickButton}>1</Button>
                   <Button handleClick={operation_Func}>-</Button>
                </div>
                <div className="row">
                    <ClearButton handleClear={handleClear}>CE</ClearButton>
                   <Button handleClick={addZeroToInput}>0</Button>
                   <Button handleClick={addDecimalToInput}>.</Button>
                   <EqualsButton handleSolve={solve}>=</EqualsButton>
                   <Button handleClick={operation_Func}>+</Button>
                </div>
            </div>

Enter fullscreen mode Exit fullscreen mode

Step 2. Functionality - Solving equations

In traditional calculator apps, hefty conditional statements are used to perform math functions, or use of Math.js is leveraged for computation. This application will solve equations simply using React Hooks and a JSON object for computation.

First lets define our Hooks:

  const [input, setInput] = useState('');
  const [prevNum, setPrevNum] = useState('');
  const [curNum, setCurNum] = useState('');
  const [operator, setOperator] = useState('');

  useEffect(() => {

// Perform computation

  }, [curNum,operator, prevNum])
Enter fullscreen mode Exit fullscreen mode

Great! Now we need a way to set our states, and perform calculations while the VDOM is re-rendering. This means we need a function for each case:

  • clickButton
    • add the number to the input
  • addZeroToInput
    • setInput only if no preceeding zero
  • addDecimalToInput
    • ensure only one decimal is inside input
  • handleClear
    • Clear all state back to initial of ''
  • solve
    • give value to the curNum
    • render solution
  • operation_Func
    • set the operator, prevNum, and initialize input

Thus with all these situations, we must now play a sort of mix and match game. This way we can understand what needs to handled, changed, or called within each of the callback functions above.

setInput setPrevNum setCurNum setOperator
ClickButton
addZero
addDecimal
clear
solve
operation_Func

Given the table above, we see how each useState function will be implemented represented by the callback functions. Implenting everything we get:

  const clickButton = (e) => {
      if(e==="+" || e==='-' ||e=== '/' ||e=== '*'){
        setOperator(e)
        console.log(e);
      } else {

        setInput(input + e);
        console.log(input);
      }  

  }
Enter fullscreen mode Exit fullscreen mode
  const handleClear = () =>{
      setInput('');
      setPrevNum('');
      setCurNum('');
      setOperator('');
  }
Enter fullscreen mode Exit fullscreen mode
  const addZeroToInput = (e)=>{
      if(input!==''){
        setInput(input + e);
        console.log(input);
      }
  }
  const addDecimalToInput = (e)=>{
      if(input.indexOf('.')=== -1){
          setInput(input+e)
          console.log(input);
      }
  }
Enter fullscreen mode Exit fullscreen mode
  const solve = () =>{
     setCurNum(input);
  }
  function operation_Func(e) {
        setPrevNum(input);
        setInput('');
        setOperator(e);
    }
Enter fullscreen mode Exit fullscreen mode

useEffect

Finally, we must get our solutions from somewhere, but avoid the VDOM render loop that is common with react. Best way to do this would be the useEffect Hook.

Once we know the operator has been set, we need a way to pass the prevNum and curNum into an equation. Most calculator apps will use if/else to perform functions, but we are not most developers! Using a JSON object we can refactor our selection process into one line of code.

We should get something like this:


  useEffect(() => {
    const math_it_Up = {
        '+': function(x,y){return x + y},
        '-': function(x,y){return x - y},
        '*':function(x,y){return x*y},
        '/':function(x,y){return x/y}
    };
    if(curNum !== ''){
        console.log(curNum);
         if(operator !== ''){
         //let solution = Math.floor(parseFloat(prevNum) + parseFloat(curNum));
         let solution = math_it_Up[operator](parseFloat(prevNum),parseFloat(curNum));
         setInput(solution);
         setOperator('');
         setCurNum('');}

    } 
  }, [curNum,operator, prevNum])
Enter fullscreen mode Exit fullscreen mode

If you'd like, you may add other equations or operations to the math_it_Up function. The final product should look something like this.

Alt Text

Follow me for more walkthroughs, tips, and bigger projects involving react, node, or css styling. Thanks!

Discussion (0)

pic
Editor guide