- ã¯ããã«
- ããã¸ã§ã¯ãã®ä½æ
- ç¶æ 管çã¨ãªã¢ã«ã¿ã¤ã 表示ã®å®è£
- æ°åãã¿ã³å¦ç
- ååæ¼ç®åãã¿ã³å¦ç
- å°æ°ç¹ãã¿ã³å¦çã¨éè¤é²æ¢ã®å®è£
- ããã¯ã¹ãã¼ã¹ãã¿ã³å¦çã¨å ¥åå¤ã®ç·¨éæ©è½ã®å®è£
- ã¯ãªã¢ãã¿ã³å¦çã¨ãªã»ããæ©è½ã®å®è£
- è¨ç®ãã¿ã³å¦çã¨ã¨ã©ã¼ãã³ããªã³ã°
- å®å ¨ãªååæ¼ç®ã®è©ä¾¡
- 表示é¨åã®å®è£
- åå¿è åãã®ã¹ã¿ã¤ãªã³ã°ä¾
- ã³ã¼ãä¿å®æ§åä¸ã®ãªãã¡ã¯ã¿ãªã³ã°
- ããã¸ã§ã¯ãã®ä½æ
ã¯ããã«
ãã®è¨äºã§ã¯ãReactã使ç¨ãã¦ã·ã³ãã«ãªè¨ç®æ©ã¢ããªãæ§ç¯ããææ³ãç´¹ä»ãã¾ãã
ãã®ã¢ããªã¯ãiOSã®iPhoneé»åã¢ããªã«ä¼¼ããã¶ã¤ã³ãæã£ã¦ãããç¹ã«åå¿è ã«åããããã¸ã§ã¯ãã§ãã
ä»åä½æããReactãã¼ã¹ã®è¨ç®æ©ã¢ããªã¯ã使ãããããéè¦ããiOSã®é»åã¢ããªã«è¦ããããããªæä½æãæä¾ãã¾ããã³ã¼ãã¯ã·ã³ãã«ã§åãããããä¿å®æ§ãé«ããªãããã«è¨è¨ãã¦ãã¾ãã
以ä¸ã®ãã¢ãéãã¦ããã®è¨äºã§ç´¹ä»ããè¨ç®æ©ã¢ããªã®åä½ã確èªã§ãã¾ãã
See the Pen React ããã¯ã§ã®ã¤ãã³ããã³ãã©ã¼ by dev.K | Webã¢ããªéçºè (@enjinia_f) on CodePen.
ãã®ãã¢ã«ç¤ºããã¦ããéãããã®è¨ç®æ©ã¢ããªã¯å ç®ãæ¸ç®ãä¹ç®ãé¤ç®ãªã©ã®åºæ¬çãªæ°å¤æ¼ç®ãè¡ããã¨ãã§ãã¾ããåºæ¬çãªååæ¼ç®ããµãã¼ããããã¨ã§ãè¨ç®ãæ軽ã«è¡ããç°å¢ãæä¾ãã¾ãã
ã¢ããªã®å®è£ ã«ã¯ãCreate-React-Appï¼CRAï¼ã使ç¨ããæ¢åã®App.jsãã¡ã¤ã«ã¨App.cssãã¡ã¤ã«ãæ´»ç¨ãã¾ããããã«ãããããã¸ã§ã¯ãã®æ§ç¯ãã¹ã ã¼ãºã«é²ã¿ãå¹ççãªéçºãå¯è½ã§ãã
è¨äºã®å¾åã§ã¯ãã³ã¼ãã®å¯èªæ§ã¨ä¿å®æ§ãåä¸ãããããã®ãªãã¡ã¯ã¿ãªã³ã°ææ³ã«ã¤ãã¦ã詳ãã解説ãã¾ããããã«ãããããã¸ã§ã¯ãã®æ¡å¼µãä¿®æ£ã容æã«ãªããé·æçãªéçºã«ããã¦ãåªããå質ãç¶æã§ããã§ãããã
æçµçã«ããã®è¨äºãéãã¦Reactã使ç¨ããã·ã³ãã«ãªè¨ç®æ©ã¢ããªã®æ§ç¯æ¹æ³ãå¦ã³ãããæ´ç·´ãããéçºã¹ãã«ã身ã«ã¤ããæå©ããã§ãããã¨ã§ãããã
ããã¸ã§ã¯ãã®ä½æ
CRAã¯ã°ãã¼ãã«ã«ã¤ã³ã¹ãã¼ã«ããã¦ããã¨æ³å®ãã¾ãã
ããã¸ã§ã¯ãã®ãã©ã«ããä½æãã¦ç§»åãã以ä¸ã®ã³ãã³ããå®è¡ãã¦Reactããã¸ã§ã¯ããä½æãã¾ãã
npx create-react-app quick-math
ä¸è¨ã®ä¾ã§ã¯ãquick-mathã¨ããååã®ããã¸ã§ã¯ããä½æããã¾ããé©åãªååã«å¤æ´ãã¦ãã ããã
ããã¸ã§ã¯ããä½æãããããä½æããããã£ã¬ã¯ããªã«ç§»åãã¾ãã
cd quick-math
以ä¸ã®ã³ãã³ãã使ç¨ãã¦ãReactã¢ããªã±ã¼ã·ã§ã³ããã¼ã«ã«ãµã¼ãã¼ã§èµ·åãã¾ãã
npm start
ãã©ã¦ã¶ã§ http://localhost:3000ã«ã¢ã¯ã»ã¹ããã¨ãæ°ããReactã¢ããªã±ã¼ã·ã§ã³ã表示ãããã¯ãã§ãã
ããã§ãCreate React Appã使ç¨ãã¦React.jsããã¸ã§ã¯ããä½æããå®è¡ããæºåãæ´ãã¾ããã
è£è¶³ã¨ãã¦ãçè¨æç¹ã§ã®Reactãã¼ã¸ã§ã³ã¯ä»¥ä¸ã¨ãªã£ã¦ãã¾ãã
// package.json "dependencies": { "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "cra-template": "1.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" },
ç¶æ 管çã¨ãªã¢ã«ã¿ã¤ã 表示ã®å®è£
æ¢åã®App.jsãã¡ã¤ã«å ã®ããã©ã«ãã³ã¼ããåé¤ãã¦ãã ããã
ã¾ããã¢ããªã®ä¸»è¦ãªæ©è½ã¯useStateããã¯ãå©ç¨ãã¦ç¶æ ã管çãããã¨ã§ãã
ããã«ãããã¦ã¼ã¶ã¼ã®å ¥åã¨è¨ç®çµæã追跡ãããªã¢ã«ã¿ã¤ã ã§ç»é¢ã«åæ ããããã¨ãã§ãã¾ãã
// App.js import React, { useState } from "react"; import "./App.css"; function App() { // Stateã®è¨å® const [input, setInput] = useState("0"); // ç¾å¨ã®å ¥åå¤ const [result, setResult] = useState(0); // è¨ç®çµæ ... }
ä¸è¨ã®ã³ã¼ãã§ã¯ãuseStateããã¯ã使ç¨ãã¦inputã¨resultã¨ãã2ã¤ã®ç¶æ å¤æ°ã宣è¨ãã¦ãã¾ããinputã¯ã¦ã¼ã¶ã¼ãå ¥åããå¤ã表ããåæå¤ã¯"0"ã§ããä¸æ¹ãresultã¯è¨ç®çµæãæ ¼ç´ããããã®ç¶æ å¤æ°ã§ãåæå¤ã¯0ã§ãã
æ°åãã¿ã³å¦ç
次ã«ãæ°åãã¿ã³ãã¯ãªãã¯ãããã¨ãã«å¼ã³åºãããhandleNumberClické¢æ°ã®å®è£ ã§ãã
// æ°åã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleNumberClick = (value) => { setInput((prevInput) => (prevInput === "0" ? value : prevInput + value)); };
ãã®é¢æ°ã¯ãsetInputé¢æ°ã使ç¨ãã¦inputç¶æ å¤æ°ãæ´æ°ãã¾ãã
ã¾ããvalueã¨ããååã®å¼æ°ã¨ãã¦åãåã£ãæ°åããå ¥åå¤ã«è¿½å ããã¾ãã
prevInput === "0"ã§ã¯ãç¾å¨ã®inputã®å¤ã"0"ã¨çãããã©ããããã§ãã¯ãã¾ãã"0"ã¨çããå ´åãã¤ã¾ãå ¥åå¤ã"0"ã®ç¶æ ã§ããå ´åãvalueã§æå®ãããæ°åãæ°ããå ¥åå¤ã¨ãã¦è¨å®ããã¾ãã
prevInput + valueã§ã¯ãå ¥åå¤ã"0"ã§ãªãå ´åãã¤ã¾ãæ¢ã«æ°åãæ¼ç®åãå«ã¾ãã¦ããå ´åãvalueã§æå®ãããæ°åãæ¢åã®å ¥åå¤ã®æ«å°¾ã«è¿½å ããã¾ãã
ãã®é¢æ°ã§ã¯ãã¯ãªãã¯ãããæ°å¤(value)ãç¾å¨ã®å ¥åå¤(prevInput)ã«è¿½å ãã¦ãã¾ãããã ããå ¥åã"0"ã®å ´åã¯ãã®ã¾ã¾ç½®ãæãããã¾ããããã«ãããæåã«0ã表示ãããå¾ã«é£ç¶ããæ°åã®å ¥åãã¹ã ã¼ãºã«è¡ããããã«ãªã£ã¦ãã¾ãã
ååæ¼ç®åãã¿ã³å¦ç
以ä¸ã¯ãååæ¼ç®åã®ãã¿ã³ãã¯ãªãã¯ãããã¨ãã«å¼ã³åºãããhandleOperatorClické¢æ°ã®å®è£ ã§ãã
// ååæ¼ç®åã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleOperatorClick = (operator) => { if (input !== "0") { setInput((prevInput) => prevInput + operator); } };
ãã®é¢æ°ã§ã¯ãsetInputé¢æ°ã使ç¨ãã¦inputç¶æ å¤æ°ãæ´æ°ãã¾ãã
ã¾ããæ¼ç®åï¼operatorã¨ããååã®å¼æ°ã¨ãã¦åãåãï¼ãæå®ããã¦ããå ´åã«ã®ã¿ãå ¥åå¤ã«æ¼ç®åã追å ãã¾ãã
ã¤ã¾ãããã®é¢æ°ãå®è¡ããã¨ãå ¥åã"0"ã§ãªãå ´åã«ã®ã¿ãã¯ãªãã¯ãããæ¼ç®å(operator)ãç¾å¨ã®å ¥åå¤ã«è¿½å ãã¦ãã¾ããããã«ãããæåã«æ¼ç®åãå ¥åãããåã«æ°åãå ¥åã§ããããã«ãªã£ã¦ãã¾ãã
å°æ°ç¹ãã¿ã³å¦çã¨éè¤é²æ¢ã®å®è£
以ä¸ã¯ãå°æ°ç¹ã®ãã¿ã³ãã¯ãªãã¯ãããéã«å¼ã³åºãããé¢æ°ã§ãã
// å°æ°ç¹ã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleDecimalClick = () => { setInput((prevInput) => (prevInput.includes(".") ? prevInput : prevInput + ".")); };
ãã®é¢æ°ã¯ãsetInputé¢æ°ã使ç¨ãã¦inputç¶æ å¤æ°ãæ´æ°ãã¾ãã
(prevInput.includes(".") ? prevInput : prevInput + ".")ã§ã¯ãç¾å¨ã®inputå¤ã«å°æ°ç¹ãå«ã¾ãã¦ãããã©ããããã§ãã¯ããå«ã¾ãã¦ããªããã°å°æ°ç¹ã追å ãã¾ãã
ãã®é¨åã®åä½ãå ·ä½çã«èª¬æãã¾ãã
prevInput.includes(".")ã¯ãç¾å¨ã®inputå¤ã«å°æ°ç¹ï¼ã.ãï¼ãå«ã¾ãã¦ãããã©ããããã§ãã¯ãã¾ããincludesã¡ã½ããã¯ãæå®ããæååã対象ã®æååã«å«ã¾ãã¦ããå ´åã«trueãè¿ããå«ã¾ãã¦ããªãå ´åã«falseãè¿ãã¾ãã
prevInput + "."ã¯ãå°æ°ç¹ãå«ã¾ãã¦ããªãå ´åãç¾å¨ã®inputå¤ã«å°æ°ç¹ã追å ãã¾ãã
ããã«ãããæ°ããå°æ°ç¹ã追å ãããinputã®å¤ãå¾ããã¾ãã
ã¤ã¾ãããã®handleDecimalClické¢æ°ãå®è¡ãããã¨ã§ãç¾å¨ã®å ¥åå¤ã«å°æ°ç¹ã追å ãã¾ãããæ¢ã«å°æ°ç¹ãå«ã¾ãã¦ããå ´åã¯è¿½å ããã¾ããã
ããã¯ã¹ãã¼ã¹ãã¿ã³å¦çã¨å ¥åå¤ã®ç·¨éæ©è½ã®å®è£
以ä¸ã¯ãããã¯ã¹ãã¼ã¹ã®ãã¿ã³ãã¯ãªãã¯ãããã¨ãã«å¼ã³åºãããé¢æ°ã®å®è£ ã§ãã
// ããã¯ã¹ãã¼ã¹ã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleBackspace = () => { setInput((prevInput) => prevInput.slice(0, prevInput.length - 1)); };
ãã®é¢æ°ã¯ãsetInputé¢æ°ã使ç¨ãã¦inputç¶æ å¤æ°ãæ´æ°ãã¾ãã
setInputï¼ inputç¶æ å¤æ°ãæ´æ°ããããã®é¢æ°ã§ãã
prevInputï¼ ç¾å¨ã®inputã®å¤ã表ãå¼æ°ã§ãã
prevInputã¨ããååã¯ä»»æã§ãããå®éã«ã¯ã©ããªååã§ãæ§ãã¾ããããä¸è¬çã«åã®ç¶æ ã示ãprevã¾ãã¯prevãä»ãããã¨ãããããã¾ãã
prevInput.slice(0, prevInput.length - 1)ï¼ ç¾å¨ã®inputå¤ã®æ«å°¾ãã1æåãåé¤ããå¦çãè¡ãã¾ãã
sliceã¡ã½ããã¯ãæå®ããã¤ã³ããã¯ã¹ã®ç¯å²ã®è¦ç´ ãåå¾ããã¡ã½ããã§ããããã§ã¯ãæååã®å é ããæ«å°¾ã®1æåæåã¾ã§ã®ç¯å²ãåå¾ãã¦ãã¾ããã¤ã¾ããæ«å°¾ã®1æåãåé¤ããã¾ãã
ãã®é¢æ°ãå®è¡ãããã¨ã§ãå ¥åå¤ã®æå¾ã®æåã1æååé¤ããã¾ãã
ä¾ãã°ãå ¥åå¤ã"12345"ã ã£ãå ´åãhandleBackspaceé¢æ°ãå®è¡ããã¨inputã®å¤ã¯"1234"ã«ãªãã¾ãã
ã¯ãªã¢ãã¿ã³å¦çã¨ãªã»ããæ©è½ã®å®è£
以ä¸ã®handleClearã¯ãã¯ãªã¢ã®ãã¿ã³ãã¯ãªãã¯ãããã¨ãã«å¼ã³åºãããé¢æ°ã®å®è£ ã§ãã
// ã¯ãªã¢ã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleClear = () => { setResult(0); setInput("0"); };
ãã®é¢æ°ã¯2ã¤ã®ç¶æ å¤æ°ãåæå¤ã«æ»ãããã®å¦çãè¡ã£ã¦ãã¾ãã
setResult(0): resultç¶æ å¤æ°ã0ã«è¨å®ãã¦ãã¾ãã
setInput("0"): inputç¶æ å¤æ°ã"0"ã«è¨å®ãã¦ãã¾ãã
ããã«ãããã¯ãªã¢ãã¿ã³ãæ¼ãããã¨ãå ¥åå¤ã"0"ã«ãªã»ãããããè¨ç®çµæã0ã«ãªã»ããããã¾ãã
è¨ç®ãã¿ã³å¦çã¨ã¨ã©ã¼ãã³ããªã³ã°
以ä¸ã¯ãè¨ç®ãã¿ã³ãã¯ãªãã¯ãããã¨ãã«å¼ã³åºãããhandleCalculateé¢æ°ã®å¦çã¨ãªãã¾ãã
// è¨ç®ã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleCalculate = () => { try { const calculatedResult = evaluateExpression(input); setInput(calculatedResult.toString()); setResult(calculatedResult); } catch (error) { setInput("ã¨ã©ã¼ï¼" + error.message); setResult("ã¨ã©ã¼"); } };
ä¸è¨ã§ã¯ãè¨ç®ã®ãã¿ã³ãã¯ãªãã¯ãããéã«å¼ã³åºãããé¢æ°ã®å¦çã§ãã
evaluateExpressioné¢æ°ã使ç¨ãã¦å ¥åãããå¼ãè©ä¾¡ããçµæã表示ãã¾ãã
ã¾ããã¨ã©ã¼ãçºçããå ´åã¯ã¨ã©ã¼ã¡ãã»ã¼ã¸ã表示ãã¾ãã
ãã ããã¨ã©ã¼å¦çã¨ã¨ã©ã¼ã¡ãã»ã¼ã¸è¡¨ç¤ºã«ã¯æ¹åã®ä½å°ãããã¾ãã
ç¾å¨ã®å®è£ ã§ã¯ãã¨ã©ã¼ã¡ãã»ã¼ã¸ãå ¥åãã£ã¼ã«ãã¨çµæãã£ã¼ã«ãã®æååã¨ãã¦ç´æ¥è¨å®ãã¾ãããããã¯ã¨ã©ã¼ã表示ããæãã¦ã¼ã¶ã¼ãã¬ã³ããªã¼ãªæ¹æ³ã§ã¯ãªãå¯è½æ§ãããã¾ãã
代ããã«ãã¨ã©ã¼å¦çãå¼·åãã¦ãç¹å®ã®ä½¿ç¨ä¾ãè¦ä»¶ã«åºã¥ãã¦ã¨ã©ã¼ã¡ãã»ã¼ã¸ãã«ã¹ã¿ãã¤ãºãã¦ãã ããã
ä¾ã示ãã¦ããã¾ãã
const handleCalculate = () => { try { const calculatedResult = evaluateExpression(input); setInput(calculatedResult.toString()); setResult(calculatedResult); } catch (error) { let errorMessage = "ã¨ã©ã¼ãçºçãã¾ããã"; if (error instanceof SyntaxError) { errorMessage = "å ¥åãç¡å¹ã§ãï¼å¼ã«ééãããªãã確èªãã¦ãã ããã"; } else if (error instanceof TypeError) { errorMessage = "ç¡å¹ãªæä½ã§ãï¼å¼ãæ£ãããã¨ã確èªãã¦ãã ããã"; } setInput("ã¨ã©ã¼ï¼" + errorMessage); setResult("ã¨ã©ã¼"); } };
ä¸è¨ã®ããã«ãã¨ã©ã¼å¦çãå¼·åãã¦ãããæ確ã§æçãªã¡ãã»ã¼ã¸ãã¦ã¼ã¶ã¼ã«æä¾ã§ãã¾ãã
å®å ¨ãªååæ¼ç®ã®è©ä¾¡
以ä¸ã¯ãèªåã§ååæ¼ç®ãè©ä¾¡ããããã®é¢æ°ã®å¦çã§ãã
// èªåã§ååæ¼ç®ãè©ä¾¡ããé¢æ° const evaluateExpression = (expression) => { // ä¸æ£ãªæåãåãé¤ã const sanitizedExpression = expression.replace(/[^-()\d/*+.]/g, ''); // è©ä¾¡ /* eslint-disable no-eval */ const result = Function(`"use strict";return (${sanitizedExpression})`)(); /* eslint-enable no-eval */ if (Number.isInteger(result)) { return result; // æ´æ°ã®å ´å㯠".0" ã表示ããã«ãã®ã¾ã¾è¿ã } else { return result.toFixed(2); // å°æ°ç¹ä»¥ä¸2æ¡ã§è¡¨ç¤º } };
ä¸è¨ã®evaluateExpressioné¢æ°ã¯èªåã§ååæ¼ç®ãè©ä¾¡ããããã®é¢æ°ã§ããä¸ããããå¼ããä¸æ£ãªæåãåãé¤ããFunctionã³ã³ã¹ãã©ã¯ã¿ã使ç¨ãã¦å¼ãè©ä¾¡ãã¾ãã
Functionã³ã³ã¹ãã©ã¯ã¿ã使ç¨ãã¦ãæ°ããé¢æ°ãä½æããå ´åããã®é¢æ°ã¯é常ã®ã³ã¼ãã¨ã¯ç°ãªãã³ã³ããã¹ãã§è©ä¾¡ããã¾ãã
ãã®ãããå³æ ¼ã¢ã¼ãï¼strict modeï¼ãæ示çã«æå®ããå¿ è¦ãããã¾ãã
è©ä¾¡çµæãæ´æ°ã®å ´åã¯ãã®ã¾ã¾è¿ããå°æ°ã®å ´åã¯å°æ°ç¹ä»¥ä¸2æ¡ã§è¡¨ç¤ºããã¾ãã
èªåã®è©ä¾¡é¢æ°ã¯ãå®å ¨æ§ã確ä¿ããããã«ç¹å®ã®æ¼ç®åã¨æ°å以å¤ã®æåãåãé¤ããããå³æ ¼ãªå¶å¾¡ãè¡ã£ãããããã¨ãã§ãã¾ãã
Number.isInteger()ã¯ãä¸ããããå¤ãæ´æ°ãã©ãããå¤å®ããJavaScriptã®çµã¿è¾¼ã¿é¢æ°ã§ãã
ãã®é¢æ°ã使ã£ã¦ãè¨ç®çµæãæ´æ°ã§ãããã©ããã確èªãã¦ãã¾ãã
â» ESLintã®ç¡å¹åã¨æå¹åã«ããã³ã¡ã³ãã¢ã¦ãã«ã¤ãã¦å¿é ããå¿ è¦ã¯ããã¾ãããããã¯å½ã¯ã¦ãªããã°ãã¼ãã®ä»æ§ã«ãããç¹å®ã®ã³ã¡ã³ãã¢ã¦ããæå¹ã«ãã¦ã³ã¼ãã®è¡¨ç¤ºãæ£ããè¡ãããã®æ段ã§ãã
ãã ããä»åã®Reactã³ã¼ãã§ã¯åé¡ãªããããno-evalã«ã¼ã«ã«éåããç®æã¯åå¨ãã¾ããããã®ããããããã®ç¹å®ã®ã«ã¼ã«ãç¡å¹åããå¿ è¦ã¯ããã¾ããããã³ã¡ã³ãã¢ã¦ããåé¤ãã¦ãæ§ãã¾ããã
å®å¿ãã¦ã³ã¡ã³ãã¢ã¦ããåé¤ãã¦ã³ã¼ããæ´çãã¦ãã ããã
evaluateExpressioné¢æ°ã¯ãå®å ¨ã§ä¾¿å©ãªååæ¼ç®ã®è©ä¾¡ãè¡ãããå ´åã«å½¹ç«ã¤ã§ãããã使ãæ¹ããã¹ã¿ã¼ããã°ãè¨ç®çµæãç°¡åã«åå¾ã§ããã®ã§ãæ¯é試ãã¦ã¿ã¦ãã ããã
表示é¨åã®å®è£
æå¾ã«ãè¨ç®æ©ã®å¤è¦³ã¨åä½ã¯ãè¤æ°ã®divè¦ç´ ã¨buttonè¦ç´ ã使ç¨ãã¦æ§ç¯ãã¦ãã¾ãã
// JSX return ( <div className="container"> <div className="calculator"> <h1>è¨ç®æ©</h1> <div className="input-container"> <input type="text" value={input} readOnly /> <button className="backspace-button" onClick={handleBackspace}> ⌫ </button> </div> <div> <button onClick={() => handleNumberClick("1")}>1</button> <button onClick={() => handleNumberClick("2")}>2</button> <button onClick={() => handleNumberClick("3")}>3</button> <button className="operator-button" onClick={() => handleOperatorClick("+")}>+</button> </div> <div> <button onClick={() => handleNumberClick("4")}>4</button> <button onClick={() => handleNumberClick("5")}>5</button> <button onClick={() => handleNumberClick("6")}>6</button> <button className="operator-button" onClick={() => handleOperatorClick("-")}>-</button> </div> <div> <button onClick={() => handleNumberClick("7")}>7</button> <button onClick={() => handleNumberClick("8")}>8</button> <button onClick={() => handleNumberClick("9")}>9</button> <button className="operator-button" onClick={() => handleOperatorClick("*")}>*</button> </div> <div> <button onClick={() => handleNumberClick("0")}>0</button> <button className="clear-button" onClick={handleClear}> C </button> <button className="operator-button" onClick={handleDecimalClick}>.</button> <button className="operator-button" onClick={handleCalculate}>=</button> </div> <div> <p>çµæ: {result}</p> </div> </div> </div> );
å
¨ä½ã®ã³ã³ããã¨ãã¦ã®<div className="container">
è¦ç´ ã«ã¯ãè¨ç®æ©ã®è¦ãç®å
¨ä½ãå®ç¾©ããè¦ç´ ãå«ã¾ãã¾ãã
è¨ç®æ©ã®ã¿ã¤ãã«ã<h1>è¨ç®æ©</h1>
ã§è¡¨ç¤ºããã¾ãã
å
¥åãã£ã¼ã«ãã表ã<input>
è¦ç´ ã¯ã<div className="input-container">
å
ã«é
ç½®ããã¦ã¼ã¶ã¼ã®å
¥åãåãä»ããé¨åã§ãã
valueå±æ§ã«ã¯å¤æ°inputã®å¤ã表示ãããreadOnlyå±æ§ã«ããç´æ¥å ¥åã¯ã§ãããã³ã¼ãå ã®é¢æ°ã«ãã£ã¦å¶å¾¡ãããå ¥åãè¡ããã¾ãã
è¨ç®æ©ã®æ°åãã¿ã³ã¯4ã¤ã®è¡ã«åãã¦è¡¨ç¤ºãããåè¡ã«ã¯1ã¤ã®æ¼ç®åãã¿ã³ãããã¾ãã
æ°åãã¿ã³ã¯ããããhandleNumberClické¢æ°ãå¼ã³åºãã対å¿ããæ°åãå ¥åãã£ã¼ã«ãã«è¿½å ãã¾ããæ¼ç®åãã¿ã³ã¯handleOperatorClické¢æ°ãå¼ã³åºãã対å¿ããæ¼ç®åãå ¥åãã£ã¼ã«ãã«è¿½å ãã¾ãã
è¨ç®æ©ã«ã¯ä»ã«ããããã¯ã¹ãã¼ã¹æ©è½ãå°æ°ç¹ã®è¿½å ãå ¥åã®ã¯ãªã¢ãè¨ç®çµæã®è¡¨ç¤ºãªã©ã®æ©è½ãåãã£ã¦ãã¾ãããããã®æ©è½ã¯åãã¿ã³ãã¯ãªãã¯ãããã¨ãã«å¯¾å¿ããé¢æ°ï¼handleBackspaceãhandleDecimalClickãhandleClearãhandleCalculateãªã©ï¼ãå®è¡ããããã¨ã«ãã£ã¦åä½ãã¾ãã
è¨ç®çµæã¯<p>çµæ: {result}</p>
ã§è¡¨ç¤ºãããçµæã¯å¤æ°resultã«ãã£ã¦åæ ããã¾ãã
ã¦ã¼ã¶ã¼ãæ°åãæ¼ç®åãã¿ã³ãã¯ãªãã¯ããã¨ãå ¥åãã£ã¼ã«ãã«ãããã®å¤ãåæ ãããè¨ç®ãã¿ã³ãã¯ãªãã¯ããã¨è¨ç®ãå®è¡ããã¦çµæã表示ããã¾ãã
ããã¯ã¹ãã¼ã¹ãã¿ã³ã使ç¨ãã¦å ¥åãä¿®æ£ããããã¯ãªã¢ãã¿ã³ã使ç¨ãã¦å ¥åããªã»ããããããããã¨ãã§ãã¾ãã
å ¨ä½ã³ã¼ãã¯ä»¥ä¸ã§ãã
// App.js import React, { useState } from "react"; import "./App.css"; function App() { const [input, setInput] = useState("0"); // ç¾å¨ã®å ¥åå¤ const [result, setResult] = useState(0); // è¨ç®çµæ // æ°åã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleNumberClick = (value) => { setInput((prevInput) => (prevInput === "0" ? value : prevInput + value)); }; // ååæ¼ç®åã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleOperatorClick = (operator) => { if (input !== "0") { setInput((prevInput) => prevInput + operator); } }; // å°æ°ç¹ã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleDecimalClick = () => { setInput((prevInput) => (prevInput.includes(".") ? prevInput : prevInput + ".")); }; // ããã¯ã¹ãã¼ã¹ã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleBackspace = () => { setInput((prevInput) => prevInput.slice(0, prevInput.length - 1)); }; // ã¯ãªã¢ã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleClear = () => { setResult(0); setInput("0"); }; // è¨ç®ã®ãã¿ã³ãã¯ãªãã¯ãããæã®å¦ç const handleCalculate = () => { try { const calculatedResult = evaluateExpression(input); setInput(calculatedResult.toString()); setResult(calculatedResult); } catch (error) { setInput("ã¨ã©ã¼ï¼" + error.message); setResult("ã¨ã©ã¼"); } }; // èªåã§ååæ¼ç®ãè©ä¾¡ããé¢æ° const evaluateExpression = (expression) => { // ä¸æ£ãªæåãåãé¤ã const sanitizedExpression = expression.replace(/[^-()\d/*+.]/g, ''); // è©ä¾¡ /* eslint-disable no-eval */ const result = Function(`"use strict";return (${sanitizedExpression})`)(); /* eslint-enable no-eval */ if (Number.isInteger(result)) { return result; // æ´æ°ã®å ´å㯠".0" ã表示ããã«ãã®ã¾ã¾è¿ã } else { return result.toFixed(2); // å°æ°ç¹ä»¥ä¸2æ¡ã§è¡¨ç¤º } }; return ( <div className="container"> <div className="calculator"> <h1>è¨ç®æ©</h1> <div className="input-container"> <input type="text" value={input} readOnly /> <button className="backspace-button" onClick={handleBackspace}> ⌫ </button> </div> <div> <button onClick={() => handleNumberClick("1")}>1</button> <button onClick={() => handleNumberClick("2")}>2</button> <button onClick={() => handleNumberClick("3")}>3</button> <button className="operator-button" onClick={() => handleOperatorClick("+")}>+</button> </div> <div> <button onClick={() => handleNumberClick("4")}>4</button> <button onClick={() => handleNumberClick("5")}>5</button> <button onClick={() => handleNumberClick("6")}>6</button> <button className="operator-button" onClick={() => handleOperatorClick("-")}>-</button> </div> <div> <button onClick={() => handleNumberClick("7")}>7</button> <button onClick={() => handleNumberClick("8")}>8</button> <button onClick={() => handleNumberClick("9")}>9</button> <button className="operator-button" onClick={() => handleOperatorClick("*")}>*</button> </div> <div> <button onClick={() => handleNumberClick("0")}>0</button> <button className="clear-button" onClick={handleClear}> C </button> <button className="operator-button" onClick={handleDecimalClick}>.</button> <button className="operator-button" onClick={handleCalculate}>=</button> </div> <div> <p>çµæ: {result}</p> </div> </div> </div> ); } export default App;
åå¿è åãã®ã¹ã¿ã¤ãªã³ã°ä¾
CSSã§ã¯ãè¨ç®æ©ã®è¦ãç®ã¨æä½æ§ãåä¸ãããããã«ä½¿ç¨ãã¦ãã¾ãã
ã¢ããªã®ã¹ã¿ã¤ãªã³ã°ã¯App.cssãã¡ã¤ã«ã使ç¨ãã¾ãã
/* App.css */ .container { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; } h1 { color: #fff; } p { color: #fff; } .backspace-button { background-color: #ff9800; color: white; position: absolute; top: 85px; left: 200px; opacity: 0.7; } .calculator .clear-button { width: 50px; /* ããã¹ãã«åããã¦é©åãªå¹ ãæå® */ height: 50px; margin: 5px; font-size: 20px; cursor: pointer; background-color: #ff9800; } .calculator { border: 1px solid #ccc; padding: 20px; border-radius: 10px; width: 250px; position: relative; background-color: black; } .calculator h1 { margin-bottom: 10px; } .calculator input { width: 100%; margin-bottom: 10px; padding: 5px; border: none; /* æ ãåé¤ */ outline: none; /* ãã©ã¼ã«ã¹æã®ã¢ã¦ãã©ã¤ã³ãåé¤ */ font-weight: bold; font-size: 25px; background-color: black; color: #fff; } .calculator button { width: 50px; height: 50px; margin: 5px; font-size: 20px; cursor: pointer; border-radius: 50%; /* ãã¿ã³ã丸ããã */ border: none; /* ãã¼ãã¼ãåé¤ãã¦ä¸¸ãå½¢ãä¿ã¤ */ } .operator-button { background-color: #ff9800; /* æ¼ç®åã®èæ¯è²ãçµ±ä¸ */ } .calculator button:hover { background-color: #ccc; }
以ä¸ã«ã¹ã¿ã¤ã«ã®æ¦è¦ã解説ãã¾ãã
è¨ç®æ©å ¨ä½ã®å¤æ ã¯.containerã¯ã©ã¹ã§å®ç¾©ãã¾ãããdisplay: flexã使ç¨ãã¦åè¦ç´ ã縦æ¹åã«ä¸å¤®ã«é ç½®ãã¦ãã¾ããããã«ãããç»é¢å ¨ä½ã®é«ãï¼100vhï¼ãã£ã±ãã«ã³ã³ãããåºãããã¨ãã§ãã¾ãã
è¨ç®æ©ã®ã¿ã¤ãã«ã¯h1ã¿ã°ã§è¡¨ç¤ºããããã¹ãã®è²ã¯ç½ã«æå®ãã¦ãã¾ãã
ãã¿ã³ã¯æ°åãã¿ã³ãæ¼ç®åãã¿ã³ãå°æ°ç¹ãã¿ã³ãã¯ãªã¢ãã¿ã³ãããã¯ã¹ãã¼ã¹ãã¿ã³ã®5種é¡ã§ãããããã®ãã¿ã³ã¯.calculatorã¯ã©ã¹ã§ã¾ã¨ãããã¿ã³ã®ã¹ã¿ã¤ã«ãå ±éã§é©ç¨ããã¾ãã
åãã¿ã³ã®ã¹ã¿ã¤ã«ã¯widthãheightãmarginãªã©ã®ãµã¤ãºãä½ç½ãæå®ãããã©ã³ããµã¤ãºã¯20pxã«è¨å®ãã¦ãã¾ãã
cursor: pointerãè¨å®ãã¦ããã¿ã³ã«ã«ã¼ã½ã«ãåãããã¨ãã¤ã³ã¿ã¼ãå¤ããããã«ãã¾ãããã¾ãããã¿ã³ã丸ãããããã«border-radius: 50%ã使ç¨ãã¦ãã¾ãã
æ¼ç®åãã¿ã³ã®èæ¯è²ã¯ãªã¬ã³ã¸ï¼#ff9800ï¼ã«æå®ããããã¼æã®ã¹ã¿ã¤ã«ã¯èãã°ã¬ã¼ï¼#cccï¼ã«å¤åãã¾ãã
ã¯ãªã¢ãã¿ã³ã¨ããã¯ã¹ãã¼ã¹ãã¿ã³ã«ããªã¬ã³ã¸ã®èæ¯è²ãæå®ããä½ç½®ã¯çµ¶å¯¾ä½ç½®ã§è¨å®ãã¦ãã¾ãã
è¨ç®æ©ã®ã³ã³ãã³ãé¨åï¼è¨ç®çµæ表示é¨åï¼ã¯inputã¿ã°ã§å®è£ ããå¹ ã¯è¦ªè¦ç´ ãã£ã±ãã«åºããããã«width: 100%ãæå®ãã¦ãã¾ãããã©ã³ããµã¤ãºã¯25pxã§ããããã¹ãã¯å¤ªåã«è¡¨ç¤ºããã¾ãã
èæ¯è²ã¯é»ã«è¨å®ããããã¹ãã®è²ã¯ç½ã¨ãªã£ã¦ãã¾ãã
ãããã®ã¹ã¿ã¤ã«ã«ãããè¨ç®æ©ã¢ããªã¯è¦ãç®ãã·ã³ãã«ã§ä½¿ãããããåãã¿ã³ãç´æçã«æä½ã§ããã¤ã³ã¿ã¼ãã§ã¼ã¹ãæä¾ããã¾ãã
ããããCSSã®ã¹ã¿ã¤ãªã³ã°ã¯åã ã®ããã¸ã§ã¯ãã好ã¿ã«åããã¦èªç±ã«ç·¨éãã¦ãã ãããããã¯ããã¾ã§ãç§ãã¹ã¿ã¤ãªã³ã°ããåå¿è åãã®ä¾ã§ãã
ãã¿ã³ã®ãã¶ã¤ã³ãé ç½®ãçµæ表示ã®ã¹ã¿ã¤ãªã³ã°ãªã©ãUI/UXãæ¹åããä½å°ãããã¾ããã¦ã¼ã¶ããªãã£ãåä¸ãããããã«ãè¦ãããã使ãããããèæ ®ãããã¨ãéè¦ã§ãã
ãã®ãã³ãã¬ãå ã«ãè¨ç®æ©ã®å¤è¦³ãæä½æ§ãèªå好ã¿ã«ã«ã¹ã¿ãã¤ãºãã¦ããã使ããããã¢ããªã±ã¼ã·ã§ã³ãä½æãã¦ãã ããã
以ä¸ãããã®Reactã¢ããªã®ä¸»è¦ãªé¨åã®è§£èª¬ã§ãã
ãã®ã¢ããªã¯ã¦ã¼ã¶ã¼ãæ°åã»æ¼ç®åãã¯ãªãã¯ãã¦è¨ç®å¼ãå ¥åããè¨ç®çµæã表示ããã·ã³ãã«ãªè¨ç®æ©ã¨ãªãã¾ãã
ã³ã¼ãä¿å®æ§åä¸ã®ãªãã¡ã¯ã¿ãªã³ã°
å ã®ã³ã¼ããããã·ã³ãã«ã§æ´ç·´ãããå½¢ã«åæ§ç¯ããå¯èªæ§ã¨ä¿å®æ§ãåä¸ããããã¨ãç®æãã¾ããã
以ä¸ããªãã¡ã¯ã¿ãªã³ã°å¾ã®ã³ã¼ãã§ãã
import React, { useState } from 'react'; import "./App.css"; function App() { // ã¹ãã¼ãå¤æ°ã®å®ç¾© const [input, setInput] = useState('0'); // å ¥åãããå¼ãæ°åãä¿æããã¹ãã¼ãå¤æ° const [result, setResult] = useState(0); // è¨ç®çµæãä¿æããã¹ãã¼ãå¤æ° // æ°åãæ¼ç®åã®ãã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦ç const handleButtonClick = (value) => { setInput((prevInput) => { if (isOperator(prevInput[prevInput.length - 1]) && isOperator(value)) { // ç´åã®å ¥åãæ¼ç®åã§ãããæ°ããå ¥åãæ¼ç®åã®å ´åã¯ä½ãããªã return prevInput; } else if (prevInput === '0' && !isOperator(value)) { // '0'ã®å ´åãã¤valueãæ¼ç®åã§ãªãå ´å return value; } else { return prevInput + value; } }); }; // ããã¯ã¹ãã¼ã¹ãã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦ç const handleBackspace = () => { setInput((prevInput) => prevInput.slice(0, prevInput.length - 1)); }; // ã¯ãªã¢ãã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦ç const handleClear = () => { setResult(0); setInput('0'); }; // '='ãã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦ç const handleCalculate = () => { try { const calculatedResult = evaluateExpression(input); setInput(calculatedResult.toString()); setResult(calculatedResult); } catch (error) { setInput('ã¨ã©ã¼ï¼' + error.message); setResult('ã¨ã©ã¼'); } }; // å°æ°ç¹ãã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦ç const handleDecimalClick = () => { setInput((prevInput) => (prevInput.includes('.') ? prevInput : prevInput + '.')); }; // æ¼ç®åãã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦ç const handleOperatorClick = (operator) => { if (!isOperator(input[input.length - 1])) { setInput((prevInput) => prevInput + operator); } }; // å¼ãè©ä¾¡ããé¢æ° const evaluateExpression = (expression) => { const sanitizedExpression = expression.replace(/[^-()\d/*+.]/g, ''); // æ°åãæ¼ç®åãæ¬å¼§ãããã³å°æ°ç¹ä»¥å¤ã®æåãåé¤ãã /* eslint-disable no-eval */ const result = Function(`"use strict";return (${sanitizedExpression})`)(); // Functionã³ã³ã¹ãã©ã¯ã¿ã使ã£ã¦å¼ãè©ä¾¡ãã /* eslint-enable no-eval */ return Number.isInteger(result) ? result : result.toFixed(2); // çµæãæ´æ°ãªããã®ã¾ã¾ãå°æ°ãªãå°æ°ç¹ä»¥ä¸2æ¡ã«ä¸¸ãã }; // æ¼ç®åãå«ããã©ãããå¤å®ããé¢æ° const isOperator = (value) => { return ['+', '-', '*', '=', 'C', '.'].includes(value); }; // ãã¿ã³ã®é ç½®ãå®ç¾© const buttonConfig = [ ['1', '2', '3', '+'], ['4', '5', '6', '-'], ['7', '8', '9', '*'], ['0', 'C', '.', '='], ]; return ( <div className="container"> <div className="calculator"> <h1>è¨ç®æ©</h1> <div className="input-container"> <input type="text" value={input} readOnly /> <button className="backspace-button" onClick={handleBackspace}> ⌫ </button> </div> {/* ãã¿ã³ãé ç½® */} {buttonConfig.map((row, rowIndex) => ( <div key={rowIndex}> {row.map((value) => ( <button key={value} className={`calculator-button ${value === 'C' ? 'clear-button' : ''} ${isOperator(value) ? 'operator' : ''}`} onClick={() => value === 'C' ? handleClear() : value === '=' ? handleCalculate() : value === '.' ? handleDecimalClick() : handleButtonClick(value) } > {value} </button> ))} </div> ))} <div> <p>çµæ: {result}</p> </div> </div> </div> ); } export default App;
CSSãå¤æ´ç¹ãããã¾ãã
/* App.css */ .container { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; } h1 { color: #fff; } p { color: #fff; } .backspace-button { background-color: #ff9800; color: white; position: absolute; top: 85px; left: 200px; opacity: 0.7; } .calculator .clear-button { width: 50px; /* ããã¹ãã«åããã¦é©åãªå¹ ãæå® */ height: 50px; margin: 5px; font-size: 20px; cursor: pointer; background-color: #fff; /* ã¯ãªã¢ãã¿ã³ã®èæ¯è²ãç½è²ã«è¨å® */ color: #000; /* ã¯ãªã¢ãã¿ã³ã®æåè²ãé»è²ã«è¨å® */ } .calculator { border: 1px solid #ccc; padding: 20px; border-radius: 10px; width: 250px; position: relative; background-color: black; } .calculator h1 { margin-bottom: 10px; } .calculator input { width: 100%; margin-bottom: 10px; padding: 5px; border: none; /* æ ãåé¤ */ outline: none; /* ãã©ã¼ã«ã¹æã®ã¢ã¦ãã©ã¤ã³ãåé¤ */ font-weight: bold; font-size: 25px; background-color: black; color: #fff; } .calculator button { width: 50px; height: 50px; margin: 5px; font-size: 20px; cursor: pointer; border-radius: 50%; /* ãã¿ã³ã丸ããã */ border: none; /* ãã¼ãã¼ãåé¤ãã¦ä¸¸ãå½¢ãä¿ã¤ */ } .calculator-button:hover { background-color: #ccc; /* ãã¿ã³ã®å ±éã¹ã¿ã¤ã« */ } .calculator-button.clear-button { /* Cãã¿ã³ã®ã¹ã¿ã¤ã« */ } .calculator-button.operator { background-color: #ff9800; /* æ¼ç®åãã¿ã³ã®èæ¯è²ããªã¬ã³ã¸è²ã«è¨å® */ } .calculator-button.operator:hover { background-color: #ccc; /* æ¼ç®åãã¿ã³ãããã¼ããéã®èæ¯è²ãç°è²ã«è¨å® */ }
See the Pen React ã·ã³ãã«ãªè¨ç®æ© by dev.K | Webã¢ããªéçºè (@enjinia_f) on CodePen.
å ã®ã³ã¼ãã¨æ¯è¼ãã¦ããªãã¡ã¯ã¿ãªã³ã°å¾ã¯ã³ã¼ãè¡ãå¢ãããã®ã®ããã®ä»£ããã«å¯èªæ§ãåä¸ããä¿å®æ§ãé«ã¾ã£ããã¨ã«æ³¨ç®ãã¦ãã ããã
ããã§ã¯ãããè¯ãã³ã¼ããå ·ä½çã«è¦ã¦ããã¾ãããã
ã» ãã¿ã³é ç½®ã®æé©å
ãã¿ã³ã®é ç½®ãbuttonConfigã¨ãã2次å é åã使ã£ã¦å®ç¾©ãã¾ããã
以ä¸ã®è¡ã§ã®ãªãã¡ã¯ã¿ãªã³ã°ã«ããããã¿ã³ã®é ç½®ã«é¢ããæ¹åãè¡ãã¾ããã
ãã®å¤æ´ã«ãããã³ã¼ãã®æ§é ã¨å¯èªæ§ãåä¸ããä¿å®æ§ã¨æ¡å¼µæ§ãå¼·åããã¾ããã
// ãã¿ã³ã®é ç½®ãå®ç¾© const buttonConfig = [ ['1', '2', '3', '+'], ['4', '5', '6', '-'], ['7', '8', '9', '*'], ['0', 'C', '.', '='], ];
ãªãã¡ã¯ã¿ãªã³ã°åã®ã³ã¼ãã§ã¯ãåãã¿ã³ãåå¥ã«å®ç¾©ãããéè¤ããã³ã¼ããåå¨ãã¦ãã¾ããã
ãããããªãã¡ã¯ã¿ãªã³ã°å¾ã®ã³ã¼ãã§ã¯ããã¿ã³ã®é ç½®ã2次å é åã§å®ç¾©ãããã¨ã§ãåãå¦çãå復ããå¿ è¦ããªããªãã¾ãããããã«ãããã³ã¼ãã®æ§é ãæ´ç·´ãããæ´çããã¾ããã
ããã«ã2次å é åå ã®è¦ç´ ãã«ã¼ãã使ç¨ãã¦å¦çãããã¨ã§ãã³ã¼ãã®ç°¡æ½ãã¨å¯èªæ§ãåä¸ãã¾ãããæ°ãããã¿ã³ã追å ããéããå¤æ´ãè¿ éãã¤å®¹æã«è¡ããããã«ãªãã¾ããã
2次å é åã®å°å ¥ã«ããããã¿ã³ã®é ç½®ãè¦è¦çã«æ確ã«ãªããã©ã®ãã¿ã³ãã©ã®ä½ç½®ã«é ç½®ããã¦ããããä¸ç®ã§ç解ã§ãã¾ããããã«ãããã³ã¼ãã®æå³ãæ確ã«ä¼ãããç解ã容æã«ãªãã¾ããã
ããã«ã2次å é åã使ç¨ãããã¨ã§ãæ°ãããã¿ã³ã追å ããéã®æéãåæ¸ããã¾ãããè¦ç´ ãé åã«è¿½å ããã ãã§æ°æ©è½ãå®è£ ã§ãããããæ¡å¼µæ§ãåä¸ãã¾ããã
ç·ãã¦ããã¿ã³ã®é ç½®ã«é¢ãããªãã¡ã¯ã¿ãªã³ã°ã¯ãã³ã¼ãã®æ§é åã¨æ´çã«æåããèªã¿ããããä¿å®æ§ãæ¡å¼µæ§ãåä¸ãããå¹æçãªå¤æ´ã¨è¨ãã¾ãã
ã» isOperatoré¢æ°ã®å°å ¥
æ¼ç®åãå«ããã©ãããå¤å®ããããã®isOperatoré¢æ°ãæ°ãã«å°å ¥ãã¾ããã
// æ¼ç®åãå«ããã©ãããå¤å®ããé¢æ° const isOperator = (value) => { return ['+', '-', '*', '=', 'C', '.'].includes(value); };
ãã®é¢æ°ã®å°å ¥ã«ããããªãã¡ã¯ã¿ãªã³ã°å¾ã®ã³ã¼ãã®å¯èªæ§ãåä¸ããè¨ç®ãã¿ã³ãã¯ãªãã¯ãããéã®å¦çãæ°å¤ã»æ¼ç®åãã¿ã³ã®ã¯ãªãã¯å¦çã®ä¸ã§ãããå ·ä½çã§ããããããæ¡ä»¶ã使ç¨ãããã¨ãã§ããããã«ãªãã¾ããã
ã¾ããæ¼ç®åã®ãªã¹ããå¤æ´ãããå ´åã§ããisOperatoré¢æ°ã®ä¸èº«ãä¿®æ£ããã ãã§å¯¾å¿ã§ããã¨ããæè»æ§ããããã¾ãã
ã» handleButtonClické¢æ°ã®æ¹å
ãã®è¡ã§ã¯ãããã¤ãã®æ¹åç¹ã¨å¤æ´ãè¡ãã¾ããã
ã¾ãããªãã¡ã¯ã¿ãªã³ã°åã®ã³ã¼ãã§ã¯ãè¨ç®ãã¿ã³ãã¯ãªãã¯ãããéã®å¦çãhandleCalculateé¢æ°ã«éç´ããã¦ãã¾ããããããããªãã¡ã¯ã¿ãªã³ã°å¾ã®ã³ã¼ãã«ã¯å«ã¾ãã¾ããã
代ããã«ãæ°åãæ¼ç®åã®ãã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦çãæ å½ããhandleButtonClické¢æ°ãæ°ãã«å°å ¥ããæ°å¤ãã¿ã³ã¨æ¼ç®åãã¿ã³ã®ã¯ãªãã¯å¦çãåãé¢æ°ã§å¦çããããã«ãã¾ããã
// æ°åãæ¼ç®åã®ãã¿ã³ãã¯ãªãã¯ãããã¨ãã®å¦ç const handleButtonClick = (value) => { setInput((prevInput) => { if (isOperator(prevInput[prevInput.length - 1]) && isOperator(value)) { // ç´åã®å ¥åãæ¼ç®åã§ãããæ°ããå ¥åãæ¼ç®åã®å ´åã¯ä½ãããªã return prevInput; } else if (prevInput === '0' && !isOperator(value)) { // '0'ã®å ´åãã¤valueãæ¼ç®åã§ãªãå ´å return value; } else { return prevInput + value; } }); };
ãã®å¤æ´ã«ãããã³ã¼ãã®æ§é ãããåããããããªããå¦çã®å ±éåã«ãã£ã¦ã³ã¼ãã®åå©ç¨æ§ã¨ä¿å®æ§ãåä¸ãã¾ããã
æ¡ä»¶åå²ãã·ã³ãã«ã«ãããããç´åã®å ¥åãæ¼ç®åã§ãããæ°ããå ¥åãæ¼ç®åã®å ´åã¯ä½ãããªããããªæ¡ä»¶ã追å ãã¾ãããããã«ãããé£ç¶ããæ¼ç®åã®å ¥åããä¸è¦ãª"0"ã®å ¥åãé²ããã¨ãã§ãã¾ãã
ã» æ©è½ã®é©åãªåå²ã¨è²¬ä»»ã®æ確å
evaluateExpressioné¢æ°å ã®ãªãã¡ã¯ã¿ãªã³ã°å¾ã®ã³ã¼ãã¯ããªãã¡ã¯ã¿ãªã³ã°åã®ã³ã¼ãã¨æ©è½çã«åãã§ãããããã¤ãæ¹åããããã¤ã³ããããã¾ãã
// å¼ãè©ä¾¡ããé¢æ° const evaluateExpression = (expression) => { const sanitizedExpression = expression.replace(/[^-()\d/*+.]/g, ''); // æ°åãæ¼ç®åãæ¬å¼§ãããã³å°æ°ç¹ä»¥å¤ã®æåãåé¤ãã /* eslint-disable no-eval */ const result = Function(`"use strict";return (${sanitizedExpression})`)(); // Functionã³ã³ã¹ãã©ã¯ã¿ã使ã£ã¦å¼ãè©ä¾¡ãã /* eslint-enable no-eval */ return Number.isInteger(result) ? result : result.toFixed(2); // çµæãæ´æ°ãªããã®ã¾ã¾ãå°æ°ãªãå°æ°ç¹ä»¥ä¸2æ¡ã«ä¸¸ãã };
ã¾ããæ©è½ã®åå²ã§ãã
ãªãã¡ã¯ã¿ãªã³ã°å¾ã®ã³ã¼ãã§ã¯ãä¸æ£ãªæåãåé¤ããé¨åãå¼ãè©ä¾¡ããé¨åãçµæãæ´å½¢ããé¨åãæ確ã«åãããããã«ãã¾ããã
ããã«ãããåé¨åãåä¸ã®è²¬ä»»ãæã¤ããã«ãªã£ã¦ãããã³ã¼ãã®ä¿å®æ§ãåä¸ãã¦ãã¾ãã
ããã«ãé¢æ°åããevaluateExpressionãã¨å¤æ´ãããã®é¢æ°ãã©ã®ãããªæ©è½ãæã£ã¦ããããæ確ã«ãªã£ã¦ãã¾ããããã«ãããã³ã¼ããèªã人ãé¢æ°ã®ç®çããã容æã«ç解ã§ãã¾ãã
ã¾ããã³ã¡ã³ããé©åã«æ´çãã¾ããã
å ¨ä½çã«ãã³ã¼ãã®å¯èªæ§ãåä¸ããã³ã¡ã³ããé©åã«æ´çãããæ©è½ã®åå²ãè¡ããã¦ãããã¨ã§ãã³ã¼ãã®ä¿å®æ§ãç解ããã容æã«ãªã£ã¦ãã¾ãã
çµè«
ãªãã¡ã¯ã¿ãªã³ã°å¾ã®ã³ã¼ãã¯ããªãã¡ã¯ã¿ãªã³ã°åã¨æ¯è¼ãã¦ã³ã¼ãè¡ãå¢ãããã®ã®ããã®ä»£ããã«ä¿å®æ§ã¨å¯èªæ§ãåä¸ãã¦ãã¾ãã
ãªãã¡ã¯ã¿ãªã³ã°å¾ã®ã³ã¼ãã§ã¯ããã¿ã³ã®é ç½®ã¨å¦çãå¹ççã«ç®¡çããã¦ãããåæ§ã®æä½ã«å¯¾ãã¦ã³ã¼ããç¹°ãè¿ãè¨è¿°ããããã¨ããªããªãã¾ããã
ããã«ããã³ã¼ããæ´çãããä¿å®æ§ãåä¸ãã¦ãã¾ããã¾ããæ¡å¼µæ§ãé«ã¾ã£ã¦ãããæ°ãããã¿ã³ã追å ããéã«ã¯buttonConfigã«è¦ç´ ã追å ããã ãã§æ¸ã¿ã¾ãã
ãªãã¡ã¯ã¿ãªã³ã°ã«ãã£ã¦ã³ã¼ãã®å¯èªæ§ãåä¸ããåãå¦çãå ±æããé¢æ°ã®å°å ¥ã«ãã£ã¦å¹çãåä¸ãã¾ããããã®ãããªå¤æ´ã«ãããã³ã¼ãã®ç®¡çãæ¡å¼µã容æã«ãªãã¨ãã£ãã¡ãªãããçã¾ãã¾ããã
æå¾ã«
èªåã®è©ä¾¡é¢æ°ãå®è£ ããéã«æ³¨æç¹ãããã¾ãã
æ°å¼ã®è©ä¾¡ã¯è¤éãªåé¡ã§ããããã°ã誤ã£ãè©ä¾¡ãé²ãããã«ãã¹ãã±ã¼ã¹ãå å®ããããã¨ãéè¦ã§ããã¾ããã»ãã¥ãªãã£ã«å¯¾ãã注æã¨æ éãªå ¥åæ¤è¨¼ãå¿ è¦ã§ãã
èªåã®è©ä¾¡é¢æ°ãå®è£ ããå ´åã¯ãã»ãã¥ãªãã£ã¨æ£ç¢ºæ§ã«ååãªé æ ®ããããã¨ãéè¦ã§ãã
ã¾ãããã®ã¢ããªã±ã¼ã·ã§ã³ã¯ã·ã³ãã«ãªè¨ç®æ©ã§ãããååæ¼ç®ã«ç¹åããã³ã¼ãã§ããé«åº¦ãªæ°å¦çæ©è½ï¼å¹³æ¹æ ¹ãä¸è§é¢æ°ãªã©ï¼ãã¡ã¢ãªã¼æ©è½ãå±¥æ´è¡¨ç¤ºãªã©ã¯å®è£ ãã¦ãã¾ãããå¿ è¦ã«å¿ãã¦ããããªãæ©è½ã追å ãããã¨ãã§ãã¾ãã
ããã¦ãããã©ã¼ãã³ã¹ã§ãã大ããªå¼ãè¤éãªè¨ç®ãè¡ãããå ´åã«ãå¼ã®è©ä¾¡ã«æéããããå¯è½æ§ãããã¾ããããå¹ççãªã¢ã«ã´ãªãºã ããã£ãã·ã¥ã®ä½¿ç¨ãæ¤è¨ããã¨ããã§ãããã
ãããã®æ³¨æç¹ãèæ ®ãã¦ãã¢ããªã±ã¼ã·ã§ã³ãæ¹åã»æ¡å¼µãããã¨ã§ãããå®å ¨ã§æ©è½ãè±å¯ãªè¨ç®æ©ã¢ããªã±ã¼ã·ã§ã³ãä½æã§ããããã«ãªãã¯ãã§ãã
ã©ãããå½è¨äºã®Reactã³ã¼ããåèã«ãã¦ãããè¯ãã³ã¼ãã®éçºã«åãã¦é²ãã§ããã ããã°å¹¸ãã§ãã
æ¬æ¥ã¯ä»¥ä¸ã¨ãªãã¾ãã
æå¾ã¾ã§èªãã§é ããããã¨ããããã¾ãã
ãã®è¨äºãå½¹ã«ç«ã£ãããããã¯ãã¼ã¯ã¨å ±æããã¦ããã ããã¨å¬ããã§ãã