[React] API 사용하여 암호화폐 실시간 시세 출력

nemo·2022년 2월 4일
6

Toy Project

목록 보기
4/4
post-thumbnail
post-custom-banner

암호화폐 OPEN API를 가져와 실시간 시세를 출력해보자. 국내에도 OPEN API를 제공하는 사이트들이 많지만 나는 해외 사이트인 코인파프리카를 이용했다. 해외 사이트지만 원화를 포함해서 여러 국가 화폐 단위로 출력할 수 있어 좋음.

📎 코인파프리카 (Coinpaprika)


국내 사이트 참고

거래소 JSON 명세
빗썸 (Bithumb) https://api.bithumb.com/public/ticker/ALL https://apidocs.bithumb.com/
업비트 (Upbit) https://crix-api-endpoint.upbit.com/v1/crix/candles/days/?code=CRIX.UPBIT.KRW-BTC https://docs.upbit.com/docs/upbit-quotation-restful-api
코인원 (Coinone) https://api.coinone.co.kr/ticker?currency=all https://doc.coinone.co.kr/


개발 환경

  • React, TypeScript, SCSS


JSON 뜯어보기

{
  "id": "btc-bitcoin", // 아이디
  "name": "Bitcoin", // 종목
  "symbol": "BTC", // 기호
  "rank": 1, // 순위
  "circulating_supply": 18948350, // 현재까지 유통량
  "total_supply": 18948362, // 총 유통량
  "max_supply": 21000000, // 최대 발행량
  "beta_value": 0.907621, 
  "first_data_at": "2010-07-17T00:00:00Z",
  "last_updated": "2022-02-04T04:37:04Z",
  "quotes": {
    "KRW": { // 원화 기준
      "price": 44787707.788481764, // 현재 시세
      "volume_24h": 26542297189861.543, // 지난 24시간 거래량
      "volume_24h_change_24h": -0.29, // 지난 24시간 거래 변동률
      "market_cap": 848653162872843.5, // 시총
      "market_cap_change_24h": 0.91, // 시총 가격 변동률
      "percent_change_15m": 0.03,
      "percent_change_30m": -0.09,
      "percent_change_1h": -0.38,
      "percent_change_6h": 1.09,
      "percent_change_12h": 0.97,
      "percent_change_24h": 0.91,
      "percent_change_7d": -0.81,
      "percent_change_30d": -19.69,
      "percent_change_1y": 6.78,
      "ath_price": 82418036.9027092,
      "ath_date": "2021-11-10T16:51:15Z",
      "percent_from_price_ath": -45.66
    }
  }
},

JSON에서 필요한 정보

구분 JSON
Rank rank
종목 name
기호 symbol
가격 quotes.KRW.price
총 시가 quotes.KRW.market_cap
거래량(24H) quotes.KRW.volume_24h
변동(24H) quotes.KRW.percent_change_24h
변동(7D) quotes.KRW.percent_change_7d

📎 리스트 레퍼런스 : investing.com




코드 작성

기본 틀

import React, { useEffect, useState } from 'react';
import './App.scss';

const App = (): JSX.Element => {
  const [loading, setLoading] = useState(true);
  
  const refreshPage = ()=>{
    window.location.reload();
  }

  return (
    <section className="coin-tracker">
      <div className="title">
        <h1>암호화폐 실시간 TOP 100</h1>
        <div className="btn">
          <button onClick={ refreshPage }>새로고침</button>
        </div>
      </div>
      {/* 결과 출력 */}
      <div className="result">
        {
          loading 
          : <span className="loader">Loading...</span>
          ? // 로딩이 끝나면 결과 출력
        }
      </div>
    </section>
  )
}

fetch 사용하여 데이터 가져오기

데이터 전체 양이 어마어마하기 때문에 TOP 100까지만 가져오는 코드를 작성했다.

// 데이터 담을 곳
const [coins, setCoins] = useState([]);

useEffect(() => {
  fetch("https://api.coinpaprika.com/v1/tickers?quotes=KRW")
    .then(response => response.json())
    .then(json => {
    setCoins(json.slice(0, 100)); // 가져온 데이터 1~100위 담기
    setLoading(false); // 로딩 멈추기
  });
}, [])

fetch를 사용하면 쌩 JSON 자료형으로 가져온다. 이 데이터를 바로 사용할 수 없기 때문에 Object 자료형으로 바꾸기 위해 json() 함수를 사용해야 한다. 참고로 axios를 사용하면 이러한 변환 과정이 필요없다.

📎 fetch() & axios & jQuery Ajax


데이터 타입 지정

interface CoinsType {
  rank: number,
    name: string,
     symbol: string,
     quotes: { 
     KRW: { 
       price: number,
       market_cap: number,
       volume_24h: number,
       percent_change_24h: number,
       percent_change_7d: number
    }
  },
}

결과 출력 영역

return (
  <div className="App">
    <section className="coin-tracker">
      <div className="title flex-grid flex-grid--center">
        <h1>암호화폐 실시간 TOP 100</h1>
        <div className="btn">
          <button onClick={ refreshPage }>새로고침</button>
        </div>
      </div>
      <div className="result">
        {
          loading
            ? <span className="loader">Loading...</span> 
            : (
            <table>
              <thead>
                <tr>
                  <th>순위</th>
                  <th>종목</th>
                  <th>기호</th>
                  <th>가격(KRW)</th>
                  <th>총 시가</th>
                  <th>거래량(24H)</th>
                  <th>변동(24H)</th>
                  <th>변동(7D)</th>
                </tr>
              </thead>
              <tbody>
                {
                  coins.map((coin: CoinsType, idx: number) => (
                    <tr key={ idx }>
                      <td>{ coin.rank }</td>
                      <td>{ coin.name }</td>
                      <td>{ coin.symbol }</td>
                      <td>{ Number(coin.quotes.KRW.price.toFixed(1)).toLocaleString() }</td>
                      <td>{ (coin.quotes.KRW.market_cap / 1000000000000).toFixed(2) }T</td>
                      <td>{ (coin.quotes.KRW.volume_24h / 1000000000000).toFixed(2) }T</td>
                      <td>{ coin.quotes.KRW.percent_change_24h.toFixed(2) }%</td>
                      <td>{ coin.quotes.KRW.percent_change_7d.toFixed(2) }%</td>
                    </tr>
                  ))
                }
                </div>
              </section>
            </div>
          );
  • T는 Trillion의 약자로 1조이고, 총 시가와 거래량을 1조로 나누고 단위를 붙였다.
  • toFixed 메서드를 사용해 소수점 자릿수를 제한했다.
  • toLocaleString 메서드를 사용해 천 단위로 콤마를 찍었다.

마무리

스타일까지 마무리하고 깃허브 페이지에 배포하면 완성!

post-custom-banner

0개의 댓글