React.js UseEffect and UseReducer Hook Example to Create Mini Arithmetic Calculator Full Project For Beginners

React.js UseEffect and UseReducer Hook Example to Create Mini Arithmetic Calculator Full Project For Beginners

 

Welcome folks today in this blog post we will be building a mini calculator in react.js using usereducer and useeffect hooks. All the full source code of the application is shown below.

 

 

Get Started

 

 

In order to get started you need to create a new react.js project and inside this you need to have the below directory structure

 

 

Here inside the public folder create a index.html file and copy paste the following code

 

index.html

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
</head>

<body>
    <noscript>
        You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
</body>

</html>

 

See also  React.js DataTable With Search and Pagination in Javascript Full Project For Beginners

 

Now create a index.js file inside the src folder and copy paste the below code

 

index.js

 

import React, { useReducer, useEffect } from "react";
import ReactDOM from "react-dom";

const initialState = {
  stage: "left",
  left: "",
  operator: "",
  right: ""
};

function calc(leftStr, operator, rightStr) {
  const left = parseInt(leftStr, 10);
  const right = parseInt(rightStr, 10);
  switch (operator) {
    case "+":
      return left + right;
    case "-":
      return left - right;
    case "×":
      return left * right;
    case "÷":
      return left / right;
    default:
      return 0;
  }
}

function reducer(state, action) {
  switch (action.type) {
    case "number":
      return {
        ...state,
        [state.stage]: state[state.stage] + action.payload
      };
    case "operator":
      return {
        ...state,
        left:
          state.stage === "right"
            ? calc(state.left, state.operator, state.right)
            : state.left,
        right: "",
        stage: "right",
        operator: action.payload
      };
    case "calculate":
      return {
        stage: "left",
        left: calc(state.left, state.operator, state.right),
        operator: "",
        right: ""
      };
    case "clear":
      return initialState;
    default:
      return state;
  }
}

const operators = ["+", "-", "*", "/"];

function App() {
  const [state, dispatch] = useReducer(reducer, initialState);

  function handleKeyDown(event) {
    const type = /[0-9]/.test(event.key)
      ? "number"
      : operators.includes(event.key)
      ? "operator"
      : ["=", "Enter"].includes(event.key)
      ? "calculate"
      : event.key === "c"
      ? "clear"
      : false;
    if (!type) return;
    return dispatch({ type, payload: event.key });
  }

  useEffect(() => {
    document.addEventListener("keydown", handleKeyDown);
    return () => document.removeEventListener("keydown", handleKeyDown);
  }, []);
  return (
    <div>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(num => (
        <button
          onClick={({ target }) =>
            dispatch({ type: "number", payload: target.textContent })
          }
        >
          {num}
        </button>
      ))}
      {operators.map(op => (
        <button
          onClick={({ target }) =>
            dispatch({ type: "operator", payload: target.textContent })
          }
        >
          {op}
        </button>
      ))}
      <button onClick={() => dispatch({ type: "calculate" })}>=</button>
      <button onClick={() => dispatch({ type: "clear" })}>C</button>
      <div
        style={{
          width: "100%",
          height: "2rem",
          marginTop: "1rem",
          padding: "0.5rem",
          backgroundColor: "hsl(170, 15%, 80%)",
          fontFamily: "monospace"
        }}
      >
        {state.left + state.operator + state.right}
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

 

See also  React.js Tutorial to Display Multiple Images as Thumbnails From Unsplash API Using react-thumbnails Library in Browser Using TypeScript Full Project For Beginners

 

And now if you run the react.js project by running the below command

 

npm run start

 

Leave a Reply