FrontEnd :-)

환전(환율) 계산기 만들기 ① FE 본문

React

환전(환율) 계산기 만들기 ① FE

code10 2023. 3. 14. 14:18

 

 

FE : React , yarn

BE: Express, npm


① First commit

우선, 백엔드 서버는 만들어 본 적이 없어서 프론트에서 환율 정보를 받아서 작동하게 했다. 환율 정보 받아오는 API 코드는 해당 홈페이지 document를 참고했다. 

1. "https://exchangerate.host/#/"에서 환율 정보 받음

2. 기본 UI

import React, { useEffect, useState } from "react";
import "./App.css";

function App() {
  const [money, setMoney] = useState(1);
  const [list, setList] = useState([]);
  const [currency1, setCurrency1] = useState("USD");
  const [currency2, setCurrency2] = useState("KRW");
  const [date, setDate] = useState("");
  const opt = list.map((v) => (
    <option value={v} key={v}>
      {v}
    </option>
  ));
  const onChange = (e) => {
    setMoney(e.target.value);
  };
  // console.log(money)
  console.log("1번째 통화", currency1, "2번째 통화", currency2);

  useEffect(() => {
    API();
    listAPI();
  }, [money, currency1, currency2]);

  const listAPI = () => {
    const currency = "USD";
    const requestURL = `https://api.exchangerate.host/latest?base=${currency}`;
    const request = new XMLHttpRequest();
    request.open("GET", requestURL);
    request.responseType = "json";
    request.send();

    request.onload = function () {
      const response = request.response;
      setDate(response.date);
      const currencyList = Object.keys(response.rates);
      setList(currencyList);
    };
  };
  const API = () => {
    console.log(currency1);
    const requestURL = `https://api.exchangerate.host/convert?from=${currency1}&to=${currency2}&amount=${money}`;
    const request = new XMLHttpRequest();
    request.open("GET", requestURL);
    request.responseType = "json";
    request.send();

    request.onload = function () {
      const response = request.response.result;
      setResultMoney(response.toFixed(2)); //소수점 2째자리까지. 3째자리에서 반올림
    };
  };
  const [resultMoney, setResultMoney] = useState();
  console.log(resultMoney);

  const handleSelected = (e) => {
    setCurrency1(e.target.value);
  };
  const handleSelected2 = (e) => {
    setCurrency2(e.target.value);
  };
  return (
    <div className="wrap">
      <header>
        <h1>환전 계산기</h1>
        <p>{date}</p>
      </header>
      <div>
        <div className="currency-box">
          <input type="number" onChange={onChange} value={money} />
          <select
            name="firstCurrency"
            value={currency1}
            onChange={handleSelected}
          >
            {opt}
          </select>
        </div>
        {/* 두번째 input */}
        <div className="currency-box">
          <input defaultValue={resultMoney}/>
          <select
            name="secondCurrency"
            value={currency2}
            onChange={handleSelected2}
          >
            {opt}
          </select>
        </div>
      </div>
    </div>
  );
}

export default App;

 

 issue

1. input 창 연동. 두 번째 input 창에서 숫자 변환하면 첫 번째 input 창 값도 변하도록.

2. option 값 통화 단위로만 표시되고 있어서 나라 이름 적용 필요

3. 서버 따로 구축 필요

4. 리팩토링 필요(컴포넌트 분리)


② Second commit

Prev issue

1. input 창 연동. 두 번째 input 창에서 숫자 변환하면 첫 번째 input 창 값도 변하도록. => 수정 완료

2. option 값 통화 단위로만 표시되고 있어서 나라 이름 적용 필요 => 나라/단위를 select 옆에 표시했으나, 가독성은 좋지 않아서 수정하면 좋을 듯. 또 선택 리스트가 너무 많고, 나라로 선택하는 게 좋을지 고민 필요. => API 새로 찾아보는 중

3. 서버 따로 구축 필요

4. 리팩토링 필요(컴포넌트 분리) => 일부.

//App.js

import React, { useEffect, useState } from "react";
import "./App.css";
import CurrencyBox from "./components/CurrencyBox";
function App() {
  const [date, setDate] = useState("");
  const [list, setList] = useState([]);
  const [rate, setRate] = useState();
  const [money, setMoney] = useState(1);
  const [inputMoney, setInputMoney] = useState(true);
  const [currency1, setCurrency1] = useState("USD"); //from
  const [currency2, setCurrency2] = useState("KRW"); //to
  const [nation1, setNation1] = useState("United States Dollar");
  const [nation2, setNation2] = useState("South Korean Won");
  let amount1, amount2;
  if (inputMoney) {
    amount1 = money;
    amount2 = money * rate;
  } else {
    amount2 = money;
    amount1 = money / rate;
  }
  const onChange1 = (e) => {
    const str = e.target.value;
    if (isNaN(str)) {
      setMoney(0);
    } else {
      const regex = /[^0-9.]+{0, 16}/g;
      const money = str.replace(regex, "");
      setMoney(money);
      setInputMoney(true);
    }
  };
  const onChange2 = (e) => {
    const str = e.target.value;
    if (isNaN(str)) {
      setMoney(0);
    } else {
      const regex = /[^0-9.]+/g;
      const money = str.replace(regex, "");
      setMoney(money);
      setInputMoney(false);
    }
  };
  const listAPI = () => {
    const currency = "USD";
      setList(currencyList);
    };
  };
  const nationAPI = () => {
    const requestURL = "https://api.exchangerate.host/symbols";
    const request = new XMLHttpRequest();
    request.open("GET", requestURL);
    request.responseType = "json";
    request.send();
    request.onload = function () {
      const response = request.response;
      const data = Object.values(response.symbols);
      for (let value of data) {
        if (value.code === currency1) {
          setNation1(value.description);
        } else if (value.code === currency2) {
          setNation2(value.description);
        }
      }
    };
  };
  const API = () => {
    const requestURL = `https://api.exchangerate.host/convert?from=${currency1}&to=${currency2}&amount=${money}`;
    const request = new XMLHttpRequest();
    request.open("GET", requestURL);
    request.send();
    request.onload = function () {
      const response = request.response;
      const exchangeRate = response.info.rate;
      setRate(exchangeRate);
    };
  };
  const opt = list.map((v) => (
    <option value={v} key={v}>
      {v}
    </option>
  ));
  const handleSelected1 = (e) => {
    setCurrency1(e.target.value);
  };
  const handleSelected2 = (e) => {
    setCurrency2(e.target.value);
  };
  useEffect(() => {
    API();
    listAPI();
    nationAPI();
  }, [money, currency1, currency2]);
  return (
    <div className="wrap">
      <header>
        <h1>환전 계산기</h1>
        <p>{date}</p>
      </header>
      <div className="currency-box">
        <CurrencyBox
          name="input1"
          opt={opt}
          selectedCurrency={currency1}
          handleSelected={handleSelected1}
          money={amount1}
          onChange={onChange1}
          nation={nation1}
        />
        <CurrencyBox
          name="input2"
          opt={opt}
          selectedCurrency={currency2}
          handleSelected={handleSelected2}
          money={amount2}
          onChange={onChange2}
          nation={nation2}
        />
      </div>
    </div>
  );
}
export default App;
//CurrencyBox.js

import React from "react";

function CurrencyBox(props) {
  const { opt, selectedCurrency, handleSelected, money, onChange, nation } = props;
  let amount
  amount = money.toLocaleString('ko-KR', {maximumFractionDigits: 2})
  
  return (
    <div className="input-row">
      <input type="text" min={0} onChange={onChange} value={amount} />
      <select value={selectedCurrency} onChange={handleSelected}>
        {opt}
      </select>
      <span>{nation}</span>
    </div>
  );
}
export default CurrencyBox;

 New issue +1. 입력창 값 관련 규칙 추가 필요: 길이 제한, NaN일 때, 00033.0 와 같이 앞에 숫자 0이 연속일 때..

'React' 카테고리의 다른 글

환전(환율) 계산기 만들기 ② FE  (0) 2023.03.14
Refresh Token과 Access Token  (0) 2022.08.01
localStorage와 sessionStorage  (0) 2022.08.01
map - 옵셔널 체이닝  (0) 2022.07.10
(react, animation) 글씨 구부려서 회전시키기  (0) 2022.07.04
Comments