How to Build a Simple Calculator App Using React Native?

by Developers for Hire
0 0
Read Time:7 Minute, 24 Second

A calculator is a simple yet useful app that is pre-installed on almost all Windows, Android, and iOS devices. However, many users aren’t happy with these pre-installed apps and their limited functionality, so they often look for better options on the App Store. You can also easily build this simple calculator app and publish it on the App Store to gain hands-on experience in app development and generate good revenue through it.

The first thing to decide before starting an app development is what development framework will be the best for your project. There are an array of frameworks available, some are compatible with native devices, while others provide compatibility to multiple devices, irrespective of their operating system.

As the calculator is a utility app, it should be built to run on multiple devices. So, you should consider using React Native for creating a calculator app. It is a JavaScript-based framework that allows seamless compatibility among different devices, operating systems, and screen sizes.

In this tutorial, we will build a simple calculator app using the React Native and Expo frameworks. Let us tell you that Expo offers a set of tools, services, and libraries to simplify the React Native code. You can easily run apps built on React Native on the Expo emulator.

Prerequisites

Before we start the development of a calculator app, here’s a list of some important files and programs that should be installed on your system:

  • Node.js
  • React Native
  • Expo

Step-wide Tutorials for Building a Calculator App Using React Native: 

Follow the below-mentioned steps to start your first app development project with React Native and Expo:

Step 1: Create a New Project

Start by creating a new project. You can create the React Native code base using the Expo CLI with the following command:

$ expo init calculator-app

Now, you can choose between the project templates. Select a blank option and use JavaScript.

After that, download all dependencies to continue the process.

Step 2: Create the Button Component

One of the best practices for developing apps with React Native is to create small and modular UI components that can be reused throughout your code.

For example, let’s create a component for a Button that we can use on different screens. To do this, we need to create a new folder called “components” where we will store our component files.

Then, we need to create a new file called Button.js where we will write the code for the Button component. Here is what the Button component looks like:

After making the code for the button component, it is essential to add styling to make it appealing. Here’s a complete code for styling the button component:

// set dimmenstion

const screen = Dimensions.get("window");

const buttonWidth = screen.width / 4;




const styles = StyleSheet.create({

  button: {

    backgroundColor: "#333333",

    flex: 1,

    height: Math.floor(buttonWidth - 10),

    alignItems: "center",

    justifyContent: "center",

    borderRadius: Math.floor(buttonWidth),

    margin: 5,

  },

  text: {

    color: "#fff",

    fontSize: 24,

  },

  textSecondary: {

    color: "#060606",

  },

  buttonDouble: {

    width: screen.width / 2 - 10,

    flex: 0,

    alignItems: "flex-start",

    paddingLeft: 40,

  },

  buttonSecondary: {

    backgroundColor: "#a6a6a6",

  },

  buttonAccent: {

    backgroundColor: "#ffc107",

  },

});

The complete code for our button component will look like this:

import { Dimensions, StyleSheet, Text, TouchableOpacity } from "react-native";

export default ({ onPress, text, size, theme }) => {

  const buttonStyles = [styles.button];

  const textStyles = [styles.text];

  if (size === "double") {

    buttonStyles.push(styles.buttonDouble);

  }

  if (theme === "secondary") {

    buttonStyles.push(styles.buttonSecondary);

    textStyles.push(styles.textSecondary);

  } else if (theme === "accent") {

    buttonStyles.push(styles.buttonAccent);

  }

  return (

    <TouchableOpacity onPress={onPress} style={buttonStyles}>

      <Text style={textStyles}>{text}</Text>

    </TouchableOpacity>

  );

};

// set dimmenstion

const screen = Dimensions.get("window");

const buttonWidth = screen.width / 4;




const styles = StyleSheet.create({

  button: {

    backgroundColor: "#333333",

    flex: 1,

    height: Math.floor(buttonWidth - 10),

    alignItems: "center",

    justifyContent: "center",

    borderRadius: Math.floor(buttonWidth),

    margin: 5,

  },

  text: {

    color: "#fff",

    fontSize: 24,

  },

  textSecondary: {

    color: "#060606",

  },

  buttonDouble: {

    width: screen.width / 2 - 10,

    flex: 0,

    alignItems: "flex-start",

    paddingLeft: 40,

  },

  buttonSecondary: {

    backgroundColor: "#a6a6a6",

  },

  buttonAccent: {

    backgroundColor: "#ffc107",

  },

});

Step 3: Create the Row Component

Creating a Row component is the next crucial step we will take on. This component is essential for building rows for processing layouts.

Here’s a complete code for the Row component and its styling:

import { StyleSheet, View } from "react-native";

const Row = ({ children }) => {

  return <View style={styles.container}>{children}</View>;

};

// create styles of Row

const styles = StyleSheet.create({

  container: {

    flexDirection: "row",

  },

});

export default Row;

Step 4: Create the Calculator Logic

The next step is to create a new folder with the name – util and a new file with the name – calculator.js. In this step, we will build function logic that will be implemented in the APp.js file of our calculator application. Here’s a complete code for creating the calculator logic:

export const initialState = {

  currentValue: "0",

  operator: null,

  previousValue: null,

};




export const handleNumber = (value, state) => {

  if (state.currentValue === "0") {

    return { currentValue: `${value}` };

  }




  return {

    currentValue: `${state.currentValue}${value}`,

  };

};




const handleEqual = (state) => {

  const { currentValue, previousValue, operator } = state;




  const current = parseFloat(currentValue);

  const previous = parseFloat(previousValue);

  const resetState = { operator: null, previousValue: null };




  switch (operator) {

    case "+":

      return {

        currentValue: `${previous + current}`,

        ...resetState,

      };

    case "-":

      return {

        currentValue: `${previous - current}`,

        ...resetState,

      };

    case "*":

      return {

        currentValue: `${previous * current}`,

        ...resetState,

      };

    case "/":

      return {

        currentValue: `${previous / current}`,

        ...resetState,

      };




    default:

      return state;

  }

};




// calculator function

const calculator = (type, value, state) => {

  switch (type) {

    case "number":

      return handleNumber(value, state);

    case "clear":

      return initialState;

    case "posneg":

      return {

        currentValue: `${parseFloat(state.currentValue) * -1}`,

      };

    case "percentage":

      return {

        currentValue: `${parseFloat(state.currentValue) * 0.01}`,

      };

    case "operator":

      return {

        operator: value,

        previousValue: state.currentValue,

        currentValue: "0",

      };

    case "equal":

      return handleEqual(state);

    default:

      return state;

  }

};




export default calculator;

Step 5: Refactor the App.js File

After creating the components and completing the logic process, it is time to make adjustments to the App.js file’s code. Here’s a complete code for refactoring the App.js file:

import React, { Component } from "react";

import { SafeAreaView, StyleSheet, Text, View } from "react-native";

import Button from "./components/Button";

import Row from "./components/Row";

import calculator, { initialState } from "./util/calculator";




// create class component of App

export default class App extends Component {

  state = initialState;




  // handle tap method

  HandleTap = (type, value) => {

    this.setState((state) => calculator(type, value, state));

  };




  // render method

  render() {

    return (

      <View style={styles.container}>

        {/* Status bae here */}

        <SafeAreaView>

          <Text style={styles.value}>

            {parseFloat(this.state.currentValue).toLocaleString()}

          </Text>




          {/* Do create componentRow */}

          <Row>

            <Button

              text="C"

              theme="secondary"

              onPress={() => this.HandleTap("clear")}

            />




            <Button

              text="+/-"

              theme="secondary"

              onPress={() => this.HandleTap("posneg")}

            />




            <Button

              text="%"

              theme="secondary"

              onPress={() => this.HandleTap("percentage")}

            />




            <Button

              text="/"

              theme="accent"

              onPress={() => this.HandleTap("operator", "/")}

            />

          </Row>




          {/* Number */}

          <Row>

            <Button text="7" onPress={() => this.HandleTap("number", 7)} />

            <Button text="8" onPress={() => this.HandleTap("number", 8)} />

            <Button text="9" onPress={() => this.HandleTap("number", 9)} />

            <Button

              text="X"

              theme="accent"

              onPress={() => this.HandleTap("operator", "*")}

            />

          </Row>




          <Row>

            <Button text="5" onPress={() => this.HandleTap("number", 5)} />

            <Button text="6" onPress={() => this.HandleTap("number", 6)} />

            <Button text="7" onPress={() => this.HandleTap("number", 7)} />

            <Button

              text="-"

              theme="accent"

              onPress={() => this.HandleTap("operator", "-")}

            />

          </Row>




          <Row>

            <Button text="1" onPress={() => this.HandleTap("number", 1)} />

            <Button text="2" onPress={() => this.HandleTap("number", 2)} />

            <Button text="3" onPress={() => this.HandleTap("number", 3)} />

            <Button

              text="+"

              theme="accent"

              onPress={() => this.HandleTap("operator", "+")}

            />

          </Row>




          <Row>

            <Button text="0" onPress={() => this.HandleTap("number", 0)} />

            <Button text="." onPress={() => this.HandleTap("number", ".")} />

            <Button

              text="="

              theme="primary"

              onPress={() => this.HandleTap("equal", "=")}

            />

          </Row>

        </SafeAreaView>

      </View>

    );

  }

}




// create styles of app

const styles = StyleSheet.create({

  container: {

    flex: 1,

    backgroundColor: "#202020",

    justifyContent: "flex-end",

  },

  value: {

    color: "#fff",

    fontSize: 42,

    textAlign: "right",

    marginRight: 20,

    marginBottom: 10,

  },

});

Step 6: Run the App

In this last step, we will try to run our application on an emulator or real device. Here we will use the iOS simulator from MacOS. Use the following command to run the program:

$ yarn ios

If your app looks and works perfectly, give it a pat on your back. If you identify any bugs or issues, consider revising the below step to find where you made mistakes. However, you can resolve these bugs to ensure it run seamlessly on all devices and operating systems.

Conclusion

That’s a wrap-up for this interactive and helpful tutorial on how to build a simple calculator using React Native. In this guide, we have tried to explain the entire process of creating button components, styling, and props in React Native and building a fully functional calculator app.

Happy
Happy
0 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
0 %

You may also like

Average Rating

5 Star
0%
4 Star
0%
3 Star
0%
2 Star
0%
1 Star
0%

Leave a Reply

Your email address will not be published. Required fields are marked *