Crypto tracker #2 Fetch

Leesu·2022년 11월 21일
0

홈페이지 만들기!
코인 랭킹 1위부터 100위까지 나오는 메인페이지를 만들어보자.


Coins.tsx (1)

  • 전부 감싸줄 컨테이너 컴포넌트, 헤더 컴포넌트, 타이틀 컴포넌트를 만든 뒤
    본격적으로 API 를 불러와 코인을 보여주기 전 임시 데이터를 불러왔다.
  • 그리고 Link 를 사용해 리스트에서 bitcoin 버튼을 클릭하면 bitcoin 페이지로 이동하게 만들어주자
import { Link } from "react-router-dom";

function Coins() {
return (
    <Container>
      <Header>
        <Title>코인</Title>
      </Header>
      <CoinsList>
        {coins.map((coin) => (
          <Coin key={coin.id}>
            <Link to={`/${coin.id}`}>{coin.name} &rarr;</Link>
          </Coin>
        ))}
      </CoinsList>
    </Container>
}
  • boom!

Fetch

  • 리액트 쿼리를 사용하기 전 우리가 알고 있는 방식으로 API로부터 데이터를 fetch 해보자!
  • https://api.coinpaprika.com/v1/coins
  • 그 전에 타입스크립트한테 내 데이터 이렇게 생겼다고 알려주자
- Coins.tsx

interface ICoin {
  id: string;
  name: string;
  symbol: string;
  rank: number;
  is_new: boolean;
  is_active: boolean;
  type: string;
}
  • 이제 fetch 갈기기
- Coins.tsx

function Coins() {
  const [coins, setCoins] = useState<ICoin[]>([]);
        // coins state가 coins 로 이루어진 array 라고 알려주기
  const [loading, setLoading] = useState(true);
  useEffect(() => {
  	(async () => {
    	const response = await
    	fetch("https://api.coinpaprika.com/v1/coins");
    	const json = await response.json();
    	setCoins(json.slice(0, 100));
    	setLoading(false);
     })();
  }, []);
  return (
    ...
  • done !
  • 랭킹 1위부터 100위까지의 코인 정보들 불러오기 성공.

Coin.tsx (1)

  • link 를 통해서 다른 화면에 정보를 보낼 수 있다?
  • 지금까지의 코드를 예로 들자면...
    • 메인페이지(coins)에서 bitcoin 을 누르면
    • url 을 통해서 coin 화면으로 우리가 누른 정보를 보내주고,
    • coin 화면이 뭘원하는지 파악해서 api 로부터 요청해서 정보를 가져다줄 것.
    • 그러나, 위의 과정이 지나가는 동안 유저는 loading 화면만 보게된다.
    • 이름 외에 나머지 정보는 실시간으로 불러온다지만.. 이름 보려고도 loading 을 기다린다..? 오마이갓.
  • 그러니, 가지고 있는 코인에 대한 정보들을, Link 태그를 통해 보내주자 (url이 아닌 보이지 않는 방식, 비하인드더씬 방식이랄까)
- Coins.tsx
	
    ...
              <Link
                to={`/${coin.id}`}
				state={{ name: coin.name }}
              >
                <Img
                  src={`https://cryptoicon-api.vercel.app/api/icon/${coin.symbol.toLowerCase()}`}
                />
                {coin.name} &rarr;
              </Link>
  • router dom 6 이상부터는 Link의 to 프롭에 모든 정보를 담지 않고
    <Link to={} state={} > 처럼 사용하도록 바뀌었기에, 참고하여 작성했다.
  • Coins.tsx 페이지를 만들었을때와 유사하므로 코드를 복사해서 붙여왔다.
- Coin.tsx 

function Coin() {
  const { coinId } = useParams<RouteParams>();
  		// 똑같이 url 의 변수 불러와주고
  const [loading, setLoading] = useState(true);
  		// coin 페이지도 정보 불러올 동안 loading 띄워줘야하니 필요하구
  const { state } = useLocation<RouteState>();
  return (
    <Container>
      <Header>
        <Title>코인 {coinId}</Title>
      </Header>
      {loading ? <Loader>Loading...</Loader> : null}
    </Container>
  );
}
  • 이제, Coins.tsx 에서 Link 태그를 통해 불러왔던
    state 의 정보를 가져와서, {coinId}{state.name} 으로 바꿔주려한다.
  • react router DOM 이 보내주는 location object에 접근하기만 하면 된다!
const location = useLocation();
console.log(location);

위와 같이 작성하면,

  • 'state' object 의 name 에 우리가 원하는 이름이 들어가 있는걸 볼 수 있다 :)
    이제 object 에서 state를 꺼내서 바로 사용해주기만 하면 됨.
- Coin.tsx 

function Coin() {
  const { coinId } = useParams<RouteParams>();
  const [loading, setLoading] = useState(true);
  const { state } = useLocation<RouteState>(); <<<----
  return (
    <Container>
      <Header>
        <Title>{state?.name || "Loading..."}</Title> <<<---- 
      </Header>
      {loading ? <Loader>Loading...</Loader> : null}
    </Container>
  );
}
  • || "Loading..." 이 있는 이유?
    • 작성해왔던 코드를 보면, Link 에 state가 포함되어있던 걸 알수 있는데
    • 이 말인 즉슨 Link 태그가 활성화가 되어야 coin 페이지로 state 정보 값을 보내준다는 것.
    • 만약 유저가 coin 페이지에 다이렉트로 접속한ㄷ면, 에러가 뜰것이다.
    • state 가 활성화 되지 않았기에 state.name 값이 없어서!!
    • 하여 만약의 상황을 대비해 위와 같이 작성한 것.
profile
기억력 안 좋은 FE 개발자의 메모장

0개의 댓글