{"id":22356481,"url":"https://github.com/dylancheetah/reactive-calculator","last_synced_at":"2026-05-04T00:32:37.748Z","repository":{"id":238193078,"uuid":"796064053","full_name":"DylanCheetah/reactive-calculator","owner":"DylanCheetah","description":"A simple desktop calculator made with React to demonstrate basic frontend web development concepts.","archived":false,"fork":false,"pushed_at":"2024-06-05T16:29:49.000Z","size":1348,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-18T20:29:21.988Z","etag":null,"topics":["calculator","frontend","nodejs","react","tutorial","web"],"latest_commit_sha":null,"homepage":"https://cybermals.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DylanCheetah.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-04T20:35:27.000Z","updated_at":"2024-06-05T16:29:52.000Z","dependencies_parsed_at":"2024-05-09T06:44:26.209Z","dependency_job_id":null,"html_url":"https://github.com/DylanCheetah/reactive-calculator","commit_stats":null,"previous_names":["dylancheetah/reactive-calculator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/DylanCheetah/reactive-calculator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DylanCheetah%2Freactive-calculator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DylanCheetah%2Freactive-calculator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DylanCheetah%2Freactive-calculator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DylanCheetah%2Freactive-calculator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DylanCheetah","download_url":"https://codeload.github.com/DylanCheetah/reactive-calculator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DylanCheetah%2Freactive-calculator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32590245,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T22:12:39.696Z","status":"ssl_error","status_checked_at":"2026-05-03T22:09:10.534Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calculator","frontend","nodejs","react","tutorial","web"],"created_at":"2024-12-04T14:10:50.053Z","updated_at":"2026-05-04T00:32:37.724Z","avatar_url":"https://github.com/DylanCheetah.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# reactive-calculator\nA simple desktop calculator made with React to demonstrate basic frontend web development concepts. A full step-by-step tutorial that teaches how to recreate this project from scratch for educational purposes is included.\n\n\n## Required Software\n* Node.js\n* Visual Studio Code\n* a web browser\n\n\n## Usage\n1. clone this repo\n2. install Node.js\n3. open a terminal to the project folder\n4. execute `npm install --save` to install the required dependencies\n5. execute `npm start` to start the backend\n6. navigate to http://localhost:8000 in your web browser\n\n\n## Tutorial\n### Phase 1: Create Minimal Backend\nBefore we can start creating our frontend, we will need a minimal backend that will simply serve our frontend to each client. We will use Express.js to create our backend and we will also use Nodemon to facilitate the development of our backend. Both of these packages will be installed via npm. We will also create a simple webpage that will serve as the basis of our frontend.\n\n01. create a folder named `reactive-calculator`\n02. open the folder in VS Code\n03. click Terminal \u003e New Terminal\n04. execute `npm init` in the terminal\n05. fill out the requested information at each prompt\n06. execute `npm install --save-dev nodemon`\n07. execute `npm install --save express`\n08. create a `public` folder inside your project folder\n09. create `public/index.html` with the following content:\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003eReactive Calculator\u003c/title\u003e\n        \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003cdiv id=\"root\"\u003eLoading...\u003c/div\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n10. create `index.js` with the following content:\n```js\n/*\n * Reactive Calculator - Backend\n *\n * This is the backend code for the calculator.\n */\n\n// Import express and create an app object\nconst express = require(\"express\");\nconst app = express();\nconst HOST = process.env.HOST || \"127.0.0.1\";\nconst PORT = parseInt(process.env.PORT || \"8000\");\n\n// Configure middleware\napp.use(express.static(\"./public\"));\n\n// Listen for incoming connections\napp.listen(PORT, HOST, () =\u003e {\n    console.log(`Listening at http://${HOST}:${PORT}/...`);\n});\n```\n11. open `package.json` and add debug and start scripts like this:\n```json\n{\n  ...\n  \"scripts\": {\n    \"debug\": \"nodemon index.js\",\n    \"start\": \"node index.js\",\n    ...\n  }\n  ...\n}\n```\n12. execute `npm run debug` to start the backend\n13. navigate to http://localhost:8000/ in your web browser and you should see this:\n![phase1](https://github.com/DylanCheetah/reactive-calculator/blob/62210358123894eb2d6b1f0e3d9e02509b9c9016/screenshots/phase1.png)\n\n\n### Phase 2: Setup React\nBefore we start writing the code for our frontend, we will need to setup React. This can be done manually or via automated tools such as `create-react-app`. In this tutorial, we will show you how to setup React manually in order to gain an in-depth understanding of how the build system works. We will be using Webpack to handle building and packaging our frontend code, Babel to compile our JSX code to plain JS code, and various Webpack loaders and plugins in order to assist with the automatic packaging process.\n\n01. click Terminal \u003e New Terminal to open another terminal\n02. execute `npm install --save-dev webpack webpack-cli babel-loader css-loader file-loader html-loader sass-loader style-loader @babel/core @babel/preset-env @babel/preset-react sass html-webpack-plugin react react-dom`\n03. create `.babelrc` with the following content:\n```json\n{\n    \"presets\": [\n        [\n            \"@babel/preset-env\",\n            {\n                \"useBuiltIns\": \"entry\",\n                \"corejs\": \"3.22\"\n            }\n        ],\n        \"@babel/preset-react\"\n    ]\n}\n```\n04. create `.browserslistrc` with the following content:\n```rc\n\u003e 0.25%\nfirefox \u003e= 52.3.0\nnot dead\n```\n05. create `webpack.config.js` with the following content:\n```js\nconst path = require(\"path\");\nconst webpack = require(\"webpack\");\nconst HTMLWebpackPlugin = require(\"html-webpack-plugin\");\n\nmodule.exports = {\n    entry: \"./src/index.js\",\n    output: {\n        filename: \"bundle.js\",\n        path: path.resolve(\"public\"),\n        publicPath: \"/\"\n    },\n    module: {\n        rules: [\n            {\n                test: /\\.(js|jsx)$/,\n                exclude: /node_modules/,\n                use: \"babel-loader\"\n            },\n            {\n                test: /\\.html$/,\n                use: \"html-loader\"\n            },\n            {\n                test: /\\.css$/,\n                use: [\"style-loader\", \"css-loader\"]\n            },\n\t\t\t{\n\t\t\t    test: /\\.scss$/,\n\t\t\t\tuse: [\"style-loader\", \"css-loader\", \"sass-loader\"]\n\t\t\t},\n\t\t\t{\n\t\t\t    test: /\\.svg$/,\n\t\t\t\tuse: \"file-loader\"\n\t\t\t}\n        ]\n    },\n    plugins: [\n        new HTMLWebpackPlugin({\n            template: \"./src/index.html\"\n        })\n    ]\n};\n```\n06. create a `src` folder inside your project folder\n07. move `public/index.html` to `src`\n08. create `src/index.js` with the following content:\n```js\n/*\n * Reactive Calculator - Frontend Entrypoint\n *\n * This is the entrypoint for the frontend.\n */\n\nimport React from \"react\";\nimport {createRoot} from \"react-dom/client\";\n\nimport App from \"./App\";\n\n\n// Create React root\nconst root = createRoot(document.querySelector(\"#root\"));\nroot.render(\u003cApp/\u003e);\n```\n09. create `src/App.js` with the following content:\n```js\n/*\n * Reactive Calculator - App Component\n *\n * This is the app component for the calculator.\n */\n\nimport React from \"react\";\n\n\n// Define app component\nfunction App() {\n    return (\n        \u003cdiv\u003eHello World!\u003c/div\u003e\n    );\n}\n\n\nexport default App;\n```\n10. open `package.json` and add a build script like this:\n```json\n{\n  ...\n  \"scripts\": {\n    \"build\": \"webpack --mode development --devtool source-map\",\n    ...\n  }\n  ...\n}\n```\n11. execute `npm run build` to do an initial build of the frontend\n12. navigate to http://localhost:8000 in your web browser and you should see this:\n![phase2](https://github.com/DylanCheetah/reactive-calculator/blob/e0424c01a428a99339c125d4befcca0977639866/screenshots/phase2.png)\n\n\n### Phase 3: Setup Bootstrap\nTo help us create a good layout and theme for our calculator, we will next setup Bootstrap. Bootstrap provides many layout and theme utilities that will be very helpful to us.\n\n1. execute `npm install --save-dev bootstrap`\n2. open `src/index.js` and add an additional import like this:\n```js\n...\nimport React from \"react\";\nimport {createRoot} from \"react-dom/client\";\n\nimport App from \"./App\";\nimport \"./styles.scss\";\n...\n```\n3. create `src/styles.scss` with the following content:\n```scss\n@import \"bootstrap/dist/css/bootstrap.min\"\n```\n4. execute `npm run build` to build the frontend again\n5. navigate to http://localhost:8000 in your web browser and you should notice that the font and margins have changed slightly:\n![phase3](https://github.com/DylanCheetah/reactive-calculator/blob/e1538a482d63022187a624ee08917b9c04d554a6/screenshots/phase3.png)\n\n\n### Phase 4: Basic UI Layout\nNow that we have our minimal backend, React, and Bootstrap setup, let's start designing the UI layout for our calculator. Bootstrap has a powerful grid based layout system that helps arrange UI elements. It also provides utilities for creating themes more easily.\n\n1. create a `components` folder inside `src`\n2. create `src/components/Display.js` with the following content:\n```js\n/*\n * Reactive Calculator - Display Component\n *\n * This component displays the current output of the calculator.\n */\n\nimport React from \"react\";\n\n\n// Define display component\nfunction Display({value}) {\n    return (\n        \u003cdiv className=\"col m-1\"\u003e\n            \u003cinput className=\"form-control text-end\" value={value}/\u003e\n        \u003c/div\u003e\n    );\n}\n\n\nexport default Display;\n```\n3. create `src/components/NumberButton.js` with the following content:\n```js\n/*\n * Reactive Calculator - Number Button Component\n *\n * This component is used to input a number.\n */\n\nimport React from \"react\";\n\n\n// Define number button component\nfunction NumberButton({value}) {\n    // Calculate layout\n    let layout = \"col\";\n\n    if([\"0\"].indexOf(value) \u003e -1) {\n        layout = \"col-8\";\n    }\n\n    return (\n        \u003cbutton className={layout + \" m-1 btn btn-primary\"}\u003e{value}\u003c/button\u003e\n    );\n}\n\n\nexport default NumberButton;\n```\n4. create `src/components/OperatorButton.js` with the following content:\n```js\n/*\n * Reactive Calculator - Operator Button Component\n *\n * This component is used to input a math operation.\n */\n\nimport React from \"react\";\n\n\n// Define operator button component\nfunction OperatorButton({op}) {\n    // Calculate layout\n    let layout = \"col\";\n\n    if([\"+\", \"=\"].indexOf(op) \u003e -1) {\n        layout = \"col-2\";\n    }\n\n    return (\n        \u003cbutton className={layout + \" m-1 btn btn-primary\"}\u003e{op}\u003c/button\u003e\n    );\n}\n\n\nexport default OperatorButton;\n```\n5. update the body of the app component in `src/App.js` like this:\n```js\n...\nfunction App() {\n    return (\n        \u003cdiv className=\"container-fluid\"\u003e\n            \u003cdiv className=\"row justify-content-center\"\u003e\n                \u003cdiv className=\"col-lg-3 col-md-4\"\u003e\n                    \u003cdiv className=\"row\"\u003e\n                        \u003cDisplay value=\"Display\"/\u003e\n                    \u003c/div\u003e\n                    \u003cdiv className=\"row\"\u003e\n                        \u003cOperatorButton op=\"C\"/\u003e\n                        \u003cOperatorButton op=\"/\"/\u003e\n                        \u003cOperatorButton op=\"*\"/\u003e\n                        \u003cOperatorButton op=\"-\"/\u003e\n                    \u003c/div\u003e\n                    \u003cdiv className=\"row\"\u003e\n                        \u003cdiv className=\"col\"\u003e\n                            \u003cdiv className=\"row\"\u003e\n                                \u003cNumberButton value=\"7\"/\u003e\n                                \u003cNumberButton value=\"8\"/\u003e\n                                \u003cNumberButton value=\"9\"/\u003e\n                            \u003c/div\u003e\n                            \u003cdiv className=\"row\"\u003e\n                                \u003cNumberButton value=\"4\"/\u003e\n                                \u003cNumberButton value=\"5\"/\u003e\n                                \u003cNumberButton value=\"6\"/\u003e\n                            \u003c/div\u003e\n                        \u003c/div\u003e\n                        \u003cOperatorButton op=\"+\"/\u003e\n                    \u003c/div\u003e\n                    \u003cdiv className=\"row\"\u003e\n                        \u003cdiv className=\"col\"\u003e\n                            \u003cdiv className=\"row\"\u003e\n                                \u003cNumberButton value=\"1\"/\u003e\n                                \u003cNumberButton value=\"2\"/\u003e\n                                \u003cNumberButton value=\"3\"/\u003e\n                            \u003c/div\u003e\n                            \u003cdiv className=\"row\"\u003e\n                                \u003cNumberButton value=\"0\"/\u003e\n                                \u003cOperatorButton op=\".\"/\u003e\n                                \u003cOperatorButton op=\"+/-\"/\u003e\n                            \u003c/div\u003e\n                        \u003c/div\u003e\n                        \u003cOperatorButton op=\"=\"/\u003e\n                    \u003c/div\u003e\n                \u003c/div\u003e\n            \u003c/div\u003e\n        \u003c/div\u003e\n    );\n}\n...\n```\n6. now build the frontend again\n7. navigate to http://localhost:8000 in your web browser and you should see the following:\n![phase4](https://github.com/DylanCheetah/reactive-calculator/blob/d70a750d18ba91b1ae86f768bddc2f41d02e4f06/screenshots/phase4.png)\n\n\n### Phase 5: Application Logic\nNow that we have created the UI layout for our application, we need to define its logic. In order to create the application logic for our calculator app, we will need to be able to manipulate the state of the application via multiple components. One way we can do this is by using a reducer. A reducer is a function that is used to update the state of an application or single component based on the current state and an action object. The reducer and state will need to be available to multiple components. The best way to do this is to utilize contexts to pass the state and dispatch function to multiple components regardless of their depth in the component tree.\n\n01. create `src/context.js` with the following content:\n```js\n/*\n * Reactive Calculator - Contexts\n *\n * This script defines the contexts for application state and dispatch.\n */\n\nimport {createContext} from \"react\";\n\n\n// Create application state and dispatch contexts\nexport const CalculatorStateCtx = createContext(null);\nexport const CalculatorDispatchCtx = createContext(null);\n```\n02. open `src/App.js`\n03. edit your imports like this:\n```js\nimport React, {useReducer} from \"react\";\n\nimport {CalculatorStateCtx, CalculatorDispatchCtx} from \"./Contexts\";\nimport Display from \"./components/Display\";\nimport NumberButton from \"./components/NumberButton\";\nimport OperatorButton from \"./components/OperatorButton\";\n```\n04. below your imports, add this code:\n```js\n// Define initial calculator state\nconst initialState = {\n    input: \"\",\n    operand1: \"\",\n    operation: \"\"\n};\n```\n05. next add the `solve` function:\n```js\n// Define utility functions\nfunction solve(state) {\n    // Ignore this action if the input is empty\n    if(state.input == \"\") {\n        return state;\n    }\n\n    // Parse both operands\n    const a = parseFloat(state.operand1);\n    const b = parseFloat(state.input);\n\n    // Solve the equation\n    let c;\n\n    switch(state.operation) {\n        case \"+\":\n            c = a + b;\n            break;\n\n        case \"-\":\n            c = a - b;\n            break;\n\n        case \"*\":\n            c = a * b;\n            break;\n\n        case \"/\":\n            c = a / b;\n            break;\n\n        default:\n            return state;\n    }\n\n    return {\n        ...state,\n        input: c.toString(),\n        operand1: \"\",\n        operation: \"\"\n    };\n}\n```\n06. then add the `reducer` function:\n```js\n// Define calculator reducer\nfunction reducer(state, action) {\n    // Handle action\n    switch(action.type) {\n        case \"PUSH_INPUT\":\n            return {\n                ...state,\n                input: state.input + action.value\n            };\n\n        case \"PUSH_DECIMAL\":\n            return {\n                ...state,\n                input: state.input.replaceAll(\".\", \"\") + \".\"\n            };\n\n        case \"TOGGLE_SIGN\":\n            // Ignore this action if the input is empty\n            if([\"\", \".\"].indexOf(state.input) \u003e -1) {\n                return state;\n            }\n\n            return {\n                ...state,\n                input: (-parseFloat(state.input)).toString()\n            };\n\n        case \"CLEAR\":\n            return {\n                ...state,\n                input: \"\",\n                operand1: \"\",\n                operation: \"\"\n            };\n\n        case \"ADD\":\n            // Ignore this action if the input is empty\n            if([\"\", \".\"].indexOf(state.input) \u003e -1) {\n                return state;\n            }\n\n            // Chain operation?\n            if(state.operand1 != \"\" \u0026\u0026 state.operation != \"\") {\n                // Solve the equation and set the operation for the next step in the chain\n                const tmpState = solve(state);\n                return {\n                    ...tmpState,\n                    input: \"\",\n                    operand1: tmpState.input,\n                    operation: \"+\"\n                };\n            }\n\n            return {\n                ...state,\n                input: \"\",\n                operand1: state.input,\n                operation: \"+\"\n            };\n\n        case \"SUBTRACT\":\n            // Ignore this action if the input is empty\n            if([\"\", \".\"].indexOf(state.input) \u003e -1) {\n                return state;\n            }\n\n            // Chain operation?\n            if(state.operand1 != \"\" \u0026\u0026 state.operation != \"\") {\n                // Solve the equation and set the operation for the next step in the chain\n                const tmpState = solve(state);\n                return {\n                    ...tmpState,\n                    input: \"\",\n                    operand1: tmpState.input,\n                    operation: \"-\"\n                };\n            }\n\n            return {\n                ...state,\n                input: \"\",\n                operand1: state.input,\n                operation: \"-\"\n            };\n        \n        case \"MULTIPLY\":\n            // Ignore this action if the input is empty\n            if([\"\", \".\"].indexOf(state.input) \u003e -1) {\n                return state;\n            }\n\n            // Chain operation?\n            if(state.operand1 != \"\" \u0026\u0026 state.operation != \"\") {\n                // Solve the equation and set the operation for the next step in the chain\n                const tmpState = solve(state);\n                return {\n                    ...tmpState,\n                    input: \"\",\n                    operand1: tmpState.input,\n                    operation: \"*\"\n                };\n            }\n\n            return {\n                ...state,\n                input: \"\",\n                operand1: state.input,\n                operation: \"*\"\n            };\n\n        case \"DIVIDE\":\n            // Ignore this action if the input is empty\n            if([\"\", \".\"].indexOf(state.input) \u003e -1) {\n                return state;\n            }\n\n            // Chain operation?\n            if(state.operand1 != \"\" \u0026\u0026 state.operation != \"\") {\n                // Solve the equation and set the operation for the next step in the chain\n                const tmpState = solve(state);\n                return {\n                    ...tmpState,\n                    input: \"\",\n                    operand1: tmpState.input,\n                    operation: \"/\"\n                };\n            }\n\n            return {\n                ...state,\n                input: \"\",\n                operand1: state.input,\n                operation: \"/\"\n            };\n\n        case \"SOLVE\":\n            return solve(state);\n\n        default:\n            return state;\n    }\n}\n```\n07. now we need to modify the body of our app component like this:\n```js\n// Define app component\nfunction App() {\n    // Initialize reducer\n    const [state, dispatch] = useReducer(reducer, initialState);\n\n    return (\n        \u003cCalculatorStateCtx.Provider value={state}\u003e\n            \u003cCalculatorDispatchCtx.Provider value={dispatch}\u003e\n                \u003cdiv className=\"container-fluid\"\u003e\n                    \u003cdiv className=\"row justify-content-center\"\u003e\n                        \u003cdiv className=\"col-lg-3 col-md-4\"\u003e\n                            \u003cdiv className=\"row\"\u003e\n                                \u003cDisplay value=\"Display\"/\u003e\n                            \u003c/div\u003e\n                            \u003cdiv className=\"row\"\u003e\n                                \u003cOperatorButton op=\"C\"/\u003e\n                                \u003cOperatorButton op=\"/\"/\u003e\n                                \u003cOperatorButton op=\"*\"/\u003e\n                                \u003cOperatorButton op=\"-\"/\u003e\n                            \u003c/div\u003e\n                            \u003cdiv className=\"row\"\u003e\n                                \u003cdiv className=\"col\"\u003e\n                                    \u003cdiv className=\"row\"\u003e\n                                        \u003cNumberButton value=\"7\"/\u003e\n                                        \u003cNumberButton value=\"8\"/\u003e\n                                        \u003cNumberButton value=\"9\"/\u003e\n                                    \u003c/div\u003e\n                                    \u003cdiv className=\"row\"\u003e\n                                        \u003cNumberButton value=\"4\"/\u003e\n                                        \u003cNumberButton value=\"5\"/\u003e\n                                        \u003cNumberButton value=\"6\"/\u003e\n                                    \u003c/div\u003e\n                                \u003c/div\u003e\n                                \u003cOperatorButton op=\"+\"/\u003e\n                            \u003c/div\u003e\n                            \u003cdiv className=\"row\"\u003e\n                                \u003cdiv className=\"col\"\u003e\n                                    \u003cdiv className=\"row\"\u003e\n                                        \u003cNumberButton value=\"1\"/\u003e\n                                        \u003cNumberButton value=\"2\"/\u003e\n                                        \u003cNumberButton value=\"3\"/\u003e\n                                    \u003c/div\u003e\n                                    \u003cdiv className=\"row\"\u003e\n                                        \u003cNumberButton value=\"0\"/\u003e\n                                        \u003cOperatorButton op=\".\"/\u003e\n                                        \u003cOperatorButton op=\"+/-\"/\u003e\n                                    \u003c/div\u003e\n                                \u003c/div\u003e\n                                \u003cOperatorButton op=\"=\"/\u003e\n                            \u003c/div\u003e\n                        \u003c/div\u003e\n                    \u003c/div\u003e\n                \u003c/div\u003e\n            \u003c/CalculatorDispatchCtx.Provider\u003e\n        \u003c/CalculatorStateCtx.Provider\u003e\n    );\n}\n```\n08. save your changes and close the file\n09. update `src/components/Display.js` like this:\n```js\n/*\n * Reactive Calculator - Display Component\n *\n * This component displays the current output of the calculator.\n */\n\nimport React, {useContext} from \"react\";\n\nimport {CalculatorStateCtx} from \"../Contexts\";\n\n\n// Define display component\nfunction Display() {\n    // Initialize state context\n    const state = useContext(CalculatorStateCtx);\n\n    return (\n        \u003cdiv className=\"col m-1\"\u003e\n            \u003cinput className=\"form-control text-end\" value={state.input} readOnly={true}/\u003e\n        \u003c/div\u003e\n    );\n}\n\n\nexport default Display;\n```\n10. update `src/components/NumberButton.js` like this:\n```js\n/*\n * Reactive Calculator - Number Button Component\n *\n * This component is used to input a number.\n */\n\nimport React, {useContext} from \"react\";\n\nimport {CalculatorDispatchCtx} from \"../Contexts\";\n\n\n// Define number button component\nfunction NumberButton({value}) {\n    // Initialize dispatch context\n    const dispatch = useContext(CalculatorDispatchCtx);\n\n    // Calculate layout\n    let layout = \"col\";\n\n    if([\"0\"].indexOf(value) \u003e -1) {\n        layout = \"col-8\";\n    }\n\n    // Define event handlers\n    const handleClick = (event) =\u003e {\n        // Dispatch push input action\n        dispatch({\n            type: \"PUSH_INPUT\",\n            value: value\n        });\n    };\n\n    return (\n        \u003cbutton className={layout + \" m-1 btn btn-primary\"} onClick={handleClick}\u003e{value}\u003c/button\u003e\n    );\n}\n\n\nexport default NumberButton;\n```\n11. update `src/components/OperatorButton.js` like this:\n```js\n/*\n * Reactive Calculator - Operator Button Component\n *\n * This component is used to input a math operation.\n */\n\nimport React, {useContext} from \"react\";\n\nimport {CalculatorDispatchCtx} from \"../Contexts\";\n\n\n// Define operator button component\nfunction OperatorButton({op}) {\n    // Initialize dispatch context\n    const dispatch = useContext(CalculatorDispatchCtx);\n\n    // Calculate layout\n    let layout = \"col\";\n\n    if([\"+\", \"=\"].indexOf(op) \u003e -1) {\n        layout = \"col-2\";\n    }\n\n    // Define event handlers\n    const handleClick = (event) =\u003e {\n        // Choose action based on operation type\n        switch(op) {\n            case \"C\":\n                // Dispatch clear action\n                dispatch({\n                    type: \"CLEAR\"\n                });\n                break;\n\n            case \".\":\n                // Dispatch push decimal action\n                dispatch({\n                    type: \"PUSH_DECIMAL\"\n                });\n                break;\n\n            case \"+/-\":\n                // Dispatch toggle sign action\n                dispatch({\n                    type: \"TOGGLE_SIGN\"\n                });\n                break;\n\n            case \"+\":\n                // Dispatch add action\n                dispatch({\n                    type: \"ADD\"\n                });\n                break;\n\n            case \"-\":\n                // Dispatch subtract action\n                dispatch({\n                    type: \"SUBTRACT\"\n                });\n                break;\n            \n            case \"*\":\n                // Dispatch multiply action\n                dispatch({\n                    type: \"MULTIPLY\"\n                });\n                break;\n\n            case \"/\":\n                // Dispatch divide action\n                dispatch({\n                    type: \"DIVIDE\"\n                });\n                break;\n\n            case \"=\":\n                // Dispatch solve action\n                dispatch({\n                    type: \"SOLVE\"\n                });\n                break;\n        }\n    };\n\n    return (\n        \u003cbutton className={layout + \" m-1 btn btn-primary\"} onClick={handleClick}\u003e{op}\u003c/button\u003e\n    );\n}\n\n\nexport default OperatorButton;\n```\n12. now build the frontend again\n13. navigate to http://localhost:8000 in your web browser and you should be able to use the calculator and get output like this:\n![phase5](https://github.com/DylanCheetah/reactive-calculator/blob/8beacb1ed43890304798404fc3e3b111e3831332/screenshots/phase5.png)\n\n\n### Phase 6: Improve UX\nAs it is right now, our calculator will not display the result of the last operation when we chain operations like `8 * 2 + 5`. We have to press the equal key before the result will be available. However, we can improve our display component so it shows the result of the last portion of the current equation as well as the current math operation. This will enhance the user experience (UX).\n\n1. open `src/components/Display.js`\n2. change the input element in your display component like this:\n```js\n...\n\u003cdiv className=\"col m-1\"\u003e\n    \u003cinput className=\"form-control text-end\" value={`${state.operand1} ${state.operation} ${state.input}`} readOnly={true}/\u003e\n\u003c/div\u003e\n...\n```\n3. build the frontend again\n4. navigate to http://localhost:8000 in your web browser and you should see the finished calculator:\n\n\n### Phase 7: Add App Icon\nFor the last phase of this tutorial, we will add an application icon. The application icon will be displayed on the browser tab and in the favorites list for our web app. To add an application icon to a web app, simply draw an icon with software such as GIMP and save it as `public/favicon.ico` within the project folder. Our calculator app is now complete.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdylancheetah%2Freactive-calculator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdylancheetah%2Freactive-calculator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdylancheetah%2Freactive-calculator/lists"}