-
Notifications
You must be signed in to change notification settings - Fork 37
[2단계 - 계산기] 유세지(김용래) 미션 제출합니다. #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
20da9e8
7bc3ae2
f50797c
be7aaea
f65ec21
ff7b23d
c6775c5
454dce8
5cd780c
74c09ba
2a55074
4d197b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,8 +2,6 @@ | |
|
|
||
| # dependencies | ||
| /node_modules | ||
| /.pnp | ||
| .pnp.js | ||
|
|
||
| # testing | ||
| /coverage | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,43 +1,20 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <html lang="ko"> | ||
| <head> | ||
| <meta charset="utf-8" /> | ||
| <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
| <meta name="theme-color" content="#000000" /> | ||
| <meta | ||
| name="description" | ||
| content="Web site created using create-react-app" | ||
| content="react-calculator created using create-react-app" | ||
| /> | ||
| <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> | ||
| <!-- | ||
| manifest.json provides metadata used when your web app is installed on a | ||
| user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ | ||
| --> | ||
| <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> | ||
| <!-- | ||
| 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> | ||
| <title>리액트 계산기</title> | ||
| </head> | ||
| <body> | ||
| <noscript>You need to enable JavaScript to run this app.</noscript> | ||
| <noscript>자바스크립트를 "사용"으로 설정해주세요.</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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,2 @@ | ||
| # https://www.robotstxt.org/robotstxt.html | ||
| User-agent: * | ||
| Disallow: |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| import React, { useEffect, useState, useCallback } from "react"; | ||
| import DisplayResult from "./component/DisplayResult"; | ||
| import NumberButton from "./component/buttons/NumberButton"; | ||
| import ModifierButton from "./component/buttons/ModifierButton"; | ||
| import OperatorButton from "./component/buttons/OperatorButton"; | ||
| import calculate from "./utils/calculate"; | ||
|
|
||
| import "./css/calculator.css"; | ||
|
|
||
| export default function App() { | ||
| const [firstNumber, setFirstNumber] = useState(0); | ||
| const [operator, setOperator] = useState(null); | ||
| const [secondNumber, setSecondNumber] = useState(0); | ||
| const [isFirstNumber, setIsFirstNumber] = useState(true); | ||
| const [result, setResult] = useState(0); | ||
|
|
||
| useEffect(() => { | ||
| const prevValue = localStorage.getItem("prevValue") || result; | ||
| setFirstNumber(Number(prevValue)); | ||
| setResult(Number(prevValue)); | ||
|
|
||
| window.addEventListener("beforeunload", function (e) { | ||
| e.preventDefault(); | ||
| e.returnValue = ""; | ||
| }); | ||
| }, []); | ||
|
|
||
| const onClickNumber = (e) => { | ||
| const inputNumber = e.target.textContent; | ||
| const resultNumber = result === 0 ? inputNumber : result + inputNumber; | ||
| setResult(resultNumber); | ||
|
|
||
| if (isFirstNumber) { | ||
| setFirstNumber(firstNumber * 10 + Number(inputNumber)); | ||
| return; | ||
| } | ||
|
|
||
| setSecondNumber(secondNumber * 10 + Number(inputNumber)); | ||
| }; | ||
|
|
||
| const onClickOperator = (e) => { | ||
| if (firstNumber === "") return; | ||
|
|
||
| const inputOperator = e.target.textContent; | ||
| if (inputOperator === "=" && secondNumber === "") return; | ||
|
|
||
| if (inputOperator !== "=") { | ||
| setResult(result + inputOperator); | ||
| setOperator(inputOperator); | ||
| setIsFirstNumber(false); | ||
| return; | ||
| } | ||
|
|
||
| onCalculate(); | ||
| }; | ||
|
|
||
| const onClickModifier = useCallback(() => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useCallback을 사용하신 이유가 있나요?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. react에서는 컴포넌트가 리렌더 될때마다 함수를 새로 만들어 할당한다고 들었습니다! |
||
| setFirstNumber(0); | ||
| setSecondNumber(0); | ||
| setOperator(null); | ||
| setIsFirstNumber(true); | ||
| setResult(0); | ||
| localStorage.setItem("prevValue", 0); | ||
| }, []); | ||
|
|
||
| const onCalculate = () => { | ||
| const res = calculate(firstNumber, secondNumber, operator); | ||
|
|
||
| if (res === Infinity || isNaN(res)) { | ||
| setFirstNumber(0); | ||
| setSecondNumber(0); | ||
| setResult("오류"); | ||
| setOperator(null); | ||
| setIsFirstNumber(true); | ||
|
Comment on lines
+70
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 다음미션부터는 setState가 많다면 한번쯤 묶어서 관리해도 되지 않나 생각해보면 좋을것 같아요
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 상태 그대로 배열로 묶어 관리하거나, 상태 관리 로직이 늘어난다면 useReducer도 사용해보겠습니다! |
||
| localStorage.setItem("prevValue", "오류"); | ||
| return; | ||
| } | ||
|
|
||
| setFirstNumber(res); | ||
| setSecondNumber(0); | ||
| setResult(res); | ||
| setOperator(null); | ||
| setIsFirstNumber(true); | ||
| localStorage.setItem("prevValue", res); | ||
| }; | ||
|
|
||
| return ( | ||
| <div id="app"> | ||
| <div className="calculator"> | ||
| <DisplayResult result={result} /> | ||
| <NumberButton onClick={onClickNumber} /> | ||
| <ModifierButton onClick={onClickModifier} /> | ||
| <OperatorButton onClick={onClickOperator} /> | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,5 @@ | ||
| import React, { Component } from "react"; | ||
| import React from "react"; | ||
|
|
||
| export default class DisplayResult extends Component { | ||
| render() { | ||
| return <h1 id="total">{this.props.result.toString()}</h1>; | ||
| } | ||
| export default function DisplayResult(props) { | ||
| return <h1 id="total">{props.result.toString()}</h1>; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
보통 실제 onClick 이벤트에 로직을 실행하는 함수들을 handle~~ 이렇게 적어놓는편이에요