본문 바로가기
웹/(React)리액트

(React) 리액트 useState 사용해서 계산기 프로그램 만들기

by 공부가싫다가도좋아 2021. 8. 20.
반응형

(React) 리액트 useState 사용해서 계산기 프로그램 만들기


* 아직 코드에 주석 설명을 달지 않았습니다. 

계산기 하나 만드는데 이렇게 어려운가.....?! 엄청 간단한줄 알았는데... 몇시간이나 걸렸다 ㅇㄴ....

계산기를 눌렀을때, 복잡한 사칙 연산 까지 가능한 계산기를 구현 하기 위해 머리를 잔뜩 굴렸다.

분명 더 간단하게 하는 방식이 있겠지만, 리액트 초보자인 나로서는 아래 풀이 방법이 최선이다... ㅠ_ㅠ 

혹시 계산기를 만드는 더 좋은 방법이 있다면 꼭 코드 공유해주세요.... ㅠㅠㅠㅠ...

 

<결과화면>

1. 복잡한 사칙연산 가능

2. 일의 자릿수 이상 자릿수의 계산 가능

3. 기호는 먼저 클릭한 것부터 계산. 

(ex. 13+17*2 => 13+17=30, 30*2=60) 

 

어려웠던 점

예를들면 (1+25-589*3+.....=??) 1+25-52 라고 가정하면,

숫자를 누르면, 1이 계산기 화면에 뜬다, 그리고 기호는 계산기 화면에 뜨지 않는다.

 

문제점은.... 일의자리 숫자만 계산할때는 매우 쉬운데 십의자리가 넘어가면서 부터 문제가 시작됐다....

"setResult(result + number_buttons[e.target.value]);"이렇게 코드를 짰더니, 

자꾸 1+25를 해야되면, 1+2를하고 나중에 5를 더해주는 것이다. 

그래서 어쩔수없이 코드구현을 했다 ㅠㅠㅠ 

숫자와 기호배열을 따로 만들고, 배열안의 숫자를 기호배열의 기호대로 순차적으로 계산해주는 방식으로 짰다.

아마 더 좋은 방법이 있을것같은데..아직까지는 모르겠당 ㅠ_ㅠ

그리고 아직 컴포넌트를 나누는거에 익숙하지 않다...!!!!! 

그래도 결과물을 만들고, useState에 대해서 한층 더 알아 갈 수 있는것에 만족한다 ㅎ_ㅎ

 

<계산기 부족한점>

원래 1+5*2 = 11이지만, 

내가 구현한 방식은 => 1+5 = 6, 6*2 = 12, 이렇게 계산되도록 구현했다.

(곱하기와 나누기부터 구현하게 할수야 있지만, 너무 비효율적인 방법밖에 더오르지 않아서 코드에는 넣지 않았다.)

 

components/Calculator.js

import React, { useState } from "react";
import "../style/Calculator.css";

let sign = "";
let calculate = "";
const Calculator = () => {
  const number_buttons = [
    "7",
    "8",
    "9",
    "%",
    "4",
    "5",
    "6",
    "x",
    "1",
    "2",
    "3",
    "-",
    "0",
    "+",
    "=",
  ];
  const [result, setResult] = useState("");

  const onClick = (e) => {
    calculate += number_buttons[e.target.value];
    if (isNaN(parseInt(number_buttons[e.target.value]))) {
      if (number_buttons[e.target.value] === "+") {
        sign = "+";
        setResult("");
      } else if (number_buttons[e.target.value] === "-") {
        sign = "-";
        setResult("");
      } else if (number_buttons[e.target.value] === "%") {
        sign = "/";
        setResult("");
      } else if (number_buttons[e.target.value] === "x") {
        sign = "*";
        setResult("");
      } else {
        let num = "";
        let num_array = [];
        let sign_array = [];
        for (let i = 0; i < calculate.length; i++) {
          if (!isNaN(calculate[i])) {
            num += calculate[i];
          } else {
            sign_array.push(calculate[i]);
            num_array.push(parseInt(num));
            num = "";
          }
        }
        num = num_array[0];
        for (let i = 0; i < sign_array.length - 1; i++) {
          if (sign_array[i] === "+") {
            num += num_array[i + 1];
          } else if (sign_array[i] === "-") {
            num -= num_array[i + 1];
          } else if (sign_array[i] === "%") {
            num /= num_array[i + 1];
          } else if (sign_array[i] === "x") {
            num *= num_array[i + 1];
          }
        }

        setResult(num);
      }
    } else {
      setResult(result + number_buttons[e.target.value]);
    }
    console.log(`sign: ${sign}`);
    console.log(calculate);
  };

  const buttons = number_buttons.map((btn, index) => (
    <li key={btn} value={index} onClick={onClick}>
      {btn}
    </li>
  ));

  return (
    <div className="container">
      <div className="calcu_container">
        <div className="calcu_result">
          <p>{result}</p>
        </div>
        <div className="numbers_input">
          <ul>{buttons}</ul>
        </div>
      </div>
    </div>
  );
};

export default Calculator;

 

style/Calculator.css

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

li {
  list-style: none;
}

.container {
  width: 100%;
  height: 500px;
  margin: 100px auto;
}

.container .calcu_container {
  width: 300px;
  height: 350px;
  margin: auto;
  border: 1px solid black;
}

.container .calcu_container .calcu_result {
  width: 240px;
  height: 50px;
  border: 1px solid #d1cdcd;
  margin: 15px auto;
  padding: 13.5px 0;
  overflow-x: auto;
  font-size: 20px;
  text-align: right;
}

.container .calcu_container .numbers_input {
  width: 240px;
  height: 300px;
  margin: auto;
}

.container .calcu_container .numbers_input ul {
  width: 250px;
  height: 100%;
  padding: 0;
  margin: 20px auto;
}

.container .calcu_container .numbers_input ul li {
  width: 60px;
  height: 60px;
  text-align: center;
  float: left;
  border: 0.1px solid #d1cdcd;
  cursor: pointer;
  padding-top: 20px;
}

.container .calcu_container .numbers_input ul li:nth-child(13) {
  width: 120px;
  height: 60px;
}

.container .calcu_container .numbers_input ul li:hover {
  background: lightcyan;
}
/*# sourceMappingURL=Calculator.css.map */

 

App.js

import Calculator from "./components/Calculator";

function App() {
  return <Calculator />;
}

export default App;

<계산기 프로그램 깃허브 레파지토리 >

https://github.com/6810779s/react_calculator

 

GitHub - 6810779s/react_calculator

Contribute to 6810779s/react_calculator development by creating an account on GitHub.

github.com

 

코드는 리액트를 배우면서 계속 개선해 보려구 한당.

반응형

댓글