환율계산기

YEONGHUN KO·2021년 11월 14일
1
post-thumbnail

1. 환율계산기

이번엔 exchange rate를 알아내기 위해서 exchange rate 사이트에서 api를 fetch해와야한다.

우선 local에서 slider를 선택하면 api에서 가져온 환율을 가져와서 적용한다.

그리고 input에 적힌 숫자를 그 환율과 곱해서 result를 표시한다.

또한 swap 버튼도 있어서 누르면 통화단위가 바뀌고 계산되어 표시된다.

1-1. 위계

  • main.js

    • App.js
      • inputValue.js
      • rate.js
      • swapButton.js
  • utils폴더

    • api.js
    • constant.js
    • validator.js
    • domStorage.js
    • storage.js

exchangerate 코드를 확인하고 싶다면 요기로에 방문해볼것

2. 배운점

- HTML

  1. Contianer > currency(2개) > currency-num > input/swap 순으로 위계질서가 형성된다는것을 알아차리자.
<div class="container">
  <div class="currency">
    <select id="currency-one">
      <option value="USD">USD</option>
      <option value="KRW" selected>KRW</option>
      <!-- 생략 -->
    </select>
    <input type="number" id="amount-one" placeholder="0" value="1" />
  </div>

  <div class="currency">
    <select id="currency-two">
      <option value="USD">USD</option>
      <option value="KRW" selected>KRW</option>
      <!-- 생략 -->
    </select>
    <input type="number" id="amount-two" placeholder="0" />
  </div>
</div>

- CSS

  1. media query를 이용해서 화면 크기 조절한 것.
@media (max-width: 600px) {
  .currency input {
    width: 40vh;
  }
  p {
    font-size: 2.5vh;
  }
}

- JS

  1. fetch를 이용해서 api를 받아온 것.

  fetch(
    `https://v6.exchangerate-api.com/v6/a1030034a3f8837e9ab84b03/latest/${currencyOne_value}`
  )
    .then(res => res.json())
    .then(data => {
      const resCurrency = data['conversion_rates'][currencyTwo_value];
      rate.innerText = `1 ${currencyOne_value} = ${resCurrency} ${currencyTwo_value}`;
      amountEl_two.value = (amountEl_one.value * resCurrency).toFixed(2);
    });
}

위의 코드를 api.js와 async/await를 통해서 더 깔끔하게 해결!

//api.js
const PERSONAL_DATA = {
  API_END_POINT: `https://v6.exchangerate-api.com/v6/a1030034a3f8837e9ab84b03/latest/`,
};

export const request = async (url, options = {}) => {
  try {
    const res = await fetch(PERSONAL_DATA.API_END_POINT + url, { ...options });
    if (!res.ok) {
      throw new Error('we ve got api issues');
    }
    return await res.json();
  } catch (error) {
    alert(error);
  }
};

//App.js

import {request} from './utils/api.js';

const fetchData = async currencyUnit => {
    const result = await request(currencyUnit);
    return result;
};

const calculate = async () => {
    const firstCurrencyData = await fetchData(firstInputCurrency);
    ...blah blah
}
  1. change/input이벤트를 통해서 변화를 감지한 것.

음.. 근데, 최종계산된 환율을 세자리 수마다 comma로 끊어서 표시하고 싶은데 can't be parsed or out of range라는 에러가 뜬다... 결과값은 전혀 문제가 없는데 parse하는 과정에서 최종환율이 string이나 number로 인식되지 않고 obj나 NAN으로 인식되는 건가?

typeof 해보니 string이라고 뜨는데... 일단 나중에 다시 디버깅 차근차근 해봐야겠다!

  • 요렇게 해결!
  const secondInputValue = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: `${secondInputCurrency}`,
}).format(firstInputValue * resultCurrency);

new Intl이라는 함수를 쓰면 됨.

  1. 알고리즘을 생각할때 중구난방으로 생각하지말고 차근차근 생각해보자.

    • firstCurrency를 바꾸면 calculate한 이후에 rate랑 secondInput을 바꿀 수 있다.(setState 로직 짜면서 든 생각.)
  2. 반복될 필요 없는 수식이 반복되고 있으면 한곳으로 모을 생각을 하자. 딱 필요한 것만 실행되도록! (setData안에 calculate를 setState로 옮긴것)


  const setData = async (currency, inputValue, whichInput) => {
    switch (whichInput) {
      case WHICH_INPUT.FIRST:
        this.setState({
          ...this.state,
          firstInputCurrency: currency,
          firstInputValue: inputValue,
        });
        break;
      case WHICH_INPUT.SECOND:
        this.setState({
          ...this.state,
          secondInputCurrency: currency,
        });
        break;
    }
    
    //calculate() => setState로 옮김
  };
  1. 생성자 함수가 같더라도 pass되는 값이 다르면 다른 컴포넌트가 됨
// App.js

const firstInput = new InputValue({
  intialState: {
    inputValueEle: amountEl_one,
    inputValue: this.state.firstInputValue,
    currencyEle: currencyEl_one,
  },
  calculate: (currency, inputValue) => {
    setData(currency, inputValue, WHICH_INPUT.FIRST);
  },
});

const secondInput = new InputValue({
  intialState: {
    inputValueEle: amountEl_two,
    inputValue: this.state.secondInputValue,
    currencyEle: currencyEl_two,
  },
  calculate: (currency, inputValue) => {
    setData(currency, inputValue, WHICH_INPUT.SECOND);
  },
});

안에 있는 state내용도 다름.

profile
'과연 이게 최선일까?' 끊임없이 생각하기

0개의 댓글