1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| import React, { useReducer } from "react"; import DigitButton from "./DigitButton"; import OperationButton from "./OperationButton"; import "./style.css";
export const ACTIONS = { ADD_DIGIT: "add-digit", CHOOSE_OPERATION: "choose-operation", CLEAR: "clear", EVALUATE: "evaluate", PERCENTAGE: "percentage", NEGATE: "negate", };
function reducer(state, { type, payload }) { switch (type) { case ACTIONS.ADD_DIGIT: if (state.overwrite) { return { ...state, currentOperand: payload.digit, overwrite: false }; } if (payload.digit === "0" && state.currentOperand === "0") return state; if (payload.digit === "." && state.currentOperand.includes(".")) return state; return { ...state, currentOperand: `${state.currentOperand || ""}${payload.digit}`, }; case ACTIONS.CHOOSE_OPERATION: if (state.currentOperand == null && state.previousOperand == null) return state; if (state.currentOperand == null) { return { ...state, operation: payload.operation }; } if (state.previousOperand == null) { return { ...state, operation: payload.operation, previousOperand: state.currentOperand, currentOperand: null, }; } return { ...state, previousOperand: evaluate(state), operation: payload.operation, currentOperand: null, }; case ACTIONS.CLEAR: return initialState; case ACTIONS.EVALUATE: if (!state.operation || !state.currentOperand || !state.previousOperand) { return state; } return { ...state, overwrite: true, previousOperand: null, operation: null, currentOperand: evaluate(state), }; case ACTIONS.PERCENTAGE: if (state.currentOperand == null) return state; return { ...state, currentOperand: (parseFloat(state.currentOperand) / 100).toString(), }; case ACTIONS.NEGATE: if (state.currentOperand == null) return state; return { ...state, currentOperand: (parseFloat(state.currentOperand) * -1).toString(), }; default: return state; } }
function evaluate({ currentOperand, previousOperand, operation }) { const prev = parseFloat(previousOperand); const current = parseFloat(currentOperand); if (isNaN(prev) || isNaN(current)) return ""; let computation = ""; switch (operation) { case "+": computation = prev + current; break; case "-": computation = prev - current; break; case "*": computation = prev * current; break; case "/": computation = prev / current; break; default: return ""; } return computation.toString(); }
const initialState = { currentOperand: "0", previousOperand: null, operation: null, };
const App = () => { const [{ currentOperand, previousOperand, operation }, dispatch] = useReducer( reducer, initialState );
return ( <div className="calculator-grid"> <div className="output"> <div className="previous-operand"> {previousOperand} {operation} </div> <div className="current-operand">{currentOperand}</div> </div> </div> ); };
export default App;
|