#5.7~
(React query가 react 버전 18부터는 tanstack query라는 이름으로 바뀌었다고 한다. 여기선 그냥 react query라고 하겠다.)
리액트 쿼리로 fetch와 state로 했던 것들을 한 번에 해결할 수 있다.
fetch로 불러온 coins의 api 정보와 state로 썼던 Loading 등을 해주는 것이다.
useQuery라는 hook을 사용해 fetcher함수(fetch를 이용하는 함수)를 부르고, fetcher함수가 loading 중인지, loading이 끝났는지를 알려준다. 그리고 json 데이터를 받아온다.
api.ts
const BASE_URL =`https://api.coinpaprika.com/v1`;
export function fetchCoins() {
return fetch(`${BASE_URL}/coins`).then((response) => response.json());
}
coins.tsx
const { isLoading, data } //isLoading이 로딩 여부 판단, data가 로딩 후 데이터 받음
= useQuery("allCoins". fetchCoins)
// 첫 번째 인자: 고유의 키값
// 두 번째 인자: fetcher 함수

주석에 있던 몇 줄의 코드가 단 한 줄이 되었다.
물론 fetchCoins가 있는 api.ts 파일을 만들긴 했으나, 그래도 훨씬 간단하게 api를 불러올 수 있는 것이다.
react query를 이용하면 로딩페이지를 볼 수 없는데 그 이유는 리액트쿼리가 api로부터 response를 캐싱하기 때문이다.
데이터가 캐시에 저장이 되기 때문에 api를 매번 불러오지 않아도 되어 로딩하는 시간이 없다는 의미이다.
ReactQueryDevtools라는 리액트 쿼리에서 제공하는 개발자 툴을 이용하면 캐시에 리액트쿼리가 캐싱한 데이터를 볼 수 있다.

콜백함수 다시 이해하기
💥 fetchCoinInfo는 () => 로 감싸서 useQuery에 넣는 이유
배경지식:
함수() = 함수를 바로 실행하겠다
함수 = 함수의 실행권한을 이벤트에 넘기겠다.(addEventListener를 생각해보자)
const {isLoading: infoLoading, data: infoData}
= useQuery(["info", coinId], ()=> fetchCoinInfo(coinId));
Coins의 fetchCoin은 그 함수 자체를 useQuery의 두번째 인자(함수가 들어가야함)로 넣었지만,
여기서 fetchCoinInfo를 익명의 화살표 함수로 한 번 감싸서 넣는 이유는
fetchCoinInfo는 api를 받아올 때 fetch에 coinId를 인자로 받아와야했다.(인자로 받는 이유:fetch 사용시 주소에 ${coinId}가 들어가기 때문!! api.ts에선 coinId를 변수에 넣어서 정의하지 않았으니까...)
그런데 인자를 받아서 api를 불러오는 함수를 useQuery에서 그대로 실행시킨다면 함수를 실행하여 리턴된 값을 넣겠다는 의미가 되어버린다.
useQuery의 두 번째 인자로는 함수가 들어가야하지 함수실행값이 들어가선 안된다.
그래서 익명함수로 한 번 감싸서 함수()를 함함수()수의 형태로 바꿔준것이다.
["info", coinId]/ ["tickers", coinId]
키 값은 고유해야하는데 둘다 coinId(coin 정보가 가진 고유한 값)로 해야하므로 배열의 첫 인자를 이름으로 하고 두 번째 인자를 키 값으로 설정.
isLoading: infoLoading/ isLoading: tickersLoading
data: infoData/ data: tickersData
얘네도 비슷한 맥락으로 두개의 query에 같은 데이터가 두 개 씩 있으니까 자바스크립트에서 object의 property(isLoading, data)를 가져온 다음 syntax를 이용해 이름을 바꿔준 것이다.
(이렇게 적어준 이유는 둘다 같은 isLoading을 쓰는데 어떤게 info/tickers에서 오는 loading인지 모르기 때문에 알려주어야한다.는 뜻..)
리액트 쿼리 끝