React study/React JS로 영화 웹 서비스 만들기

[React] 7-2. React와 api를 이용해 coin tracker 앱 만들어 보기

카누가 좋아요 2023. 6. 7. 18:12

📌 암호화폐들과 그 가격을 나열하는 앱 만들기

우리가 원하는 것은 페이지나 앱을 들어왔을 때 로딩 메세지가 보이고, 코인들이 보이면 로딩 메세지를 숨기고 코인들을 리스트로 쭉 보여주는 것이다.


1. 로딩을 위한 state를 정의한다.


loading의 초깃값은 true로 설정해 주었다.

그리고 loading이 true일 경우 화면에 Loading을 띄우고, 그렇지 않을 경우 아무것도 반환하지 않는 삼항 연산자를 이용한 코드를 작성해 주었다.


import { useState } from "react";

function App() {
  const [loading, setLoading] = useState(true); // 주목!
  return (
    <div>
      <h1>The Coins!</h1>
      {loading ? <strong>Loading...</strong> : null} // 주목!
    </div>
  );
}

export default App;



2. coin API를 불러온다.


https://api.coinpaprika.com/v1/tickers 에 많은 코인 정보가 담겨 있는 것을 볼 수 있다.


전 시간에 API의 경우 처음 한번만 render될 필요가 있다고 배웠다.

API를 state가 변경될 때마다 계속 불러오는 것은 비효율적이기 때문이다.

따라서 useEffect를 이용하여 API를 fetch하는 코드를 작성한다.


function App() {
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    fetch("https://api.coinpaprika.com/v1/tickers");
  }, []);      // 주목!
  return (
  .....

useEffect의 두 번째 인자로 빈 배열을 넘겨주면 어떤 state의 변화도 주시하지 않으므로 처음 화면이 render될 때 딱 한번만 작동된다고 배웠다.


위의 코드를 작성하고 f12를 눌러 네트워크에서 tickers를 살펴보면 GET request가 일어나서 200이라는 응답을 받은 것을 확인할 수 있다.

preview를 보면 엄청나게 많은 코인 정보에 관한 객체를 모아놓은 배열을 받은 것을 확인할 수 있다.



3. 필요한 정보를 추출해낸다.


코인 정보 객체를 모아놓은 배열이 곧 response가 되고, 그것으로부터 json을 추출해낼 것이다.


useEffect(() => {
  fetch("https://api.coinpaprika.com/v1/tickers")
    .then((response) => response.json()) // 주목!
    .then((json) => console.log(json));
}, []);

console.log(json)의 결과로 console창에 엄청나게 많은 코인 정보 객체를 담고 있는 배열이 뜨는 것을 확인할 수 있다.



4. 위에서 추출한 정보를 state에 넣는다.


위에서 추출한 데이터를 넣을 state인 coins를 생성해 준다.

그리고 setCoins를 modifier로 하여 받아온 json객체를 인자로 넣어 state로 넣어준다.


function App() {
  .....
  const [coins, setCoins] = useState([]);     // 주목!
  useEffect(() => {
    fetch("https://api.coinpaprika.com/v1/tickers")
      .then((response) => response.json())
      .then((json) => setCoins(json));     // 주목!
  }, []);
  .....



5. coin 정보 얻기를 마쳤다면, loading을 false로 바꾸어 준다.


coins state에 정보를 넣은 후에는 loading이 멈춰야 하기 때문에 setLoading 함수의 인자로 false를 넣어 loading state를 false로 만들어 준다.


useEffect(() => {
  fetch("https://api.coinpaprika.com/v1/tickers")
    .then((response) => response.json())
    .then((json) => {
      setCoins(json);
      setLoading(false); // 주목!
    });
}, []);

위의 코드를 적용하면 loading이 화면에서 빠르게 사라지는 것을 볼 수 있는데, 이는 API가 빠르게 response하고 있다는 것이다.



6. coins state에 있는 것들을 화면에 렌더링시킨다.


HTML의 리스트와 JS 문법인 map을 사용하여 받아온 정보를 화면에 띄울 수 있다.

coins는 배열을 가지고 있는 변수이므로 map 함수를 사용하여 배열 요소 하나하나에(객체 하나하나에) 접근이 가능하다.

화면에는 코인의 name, 코인 종류의 수, symbol, 그리고 price에 대한 정보를 띄울 것이다.


return (
    <div>
      <h1>The Coins! ({coins.length})</h1>     // 주목!
      .....
      <ul>     // 주목!
        {coins.map((coin) => (     // 주목!
          <li key={coin.id}>     // 주목!
            {coin.name} ({coin.symbol}) : {coin.quotes.USD.price}     // 주목!
          </li>
        ))}
      </ul>
.....

여러 개의 li를 사용하고 있기 때문에 key로 li들을 구분을 해 주어야 하는데, 코인 객체 하나하나를 살펴보면 고유한 값인 id를 하나씩 가지고 있으므로 이를 활용하였다.


* coins와 관련된 useState에서 초깃값을 빈 배열로 넣어주었는데, 이를 넣어주지 않으면(아무 인자도 넣기 않으면) coins는 처음에 undefined의 값이 들어간다.

아래에서 coins.length라는 코드가 있는데, undefined의 길이는 구할 수 없으므로 결국 프로그램에서는 에러가 발생하게 된다.

따라서 항상 초깃값을 설정해 주는 것이 좋다.