-
useQuery()FW, Lib 공부/React 2022. 6. 22. 15:43
reart-query 라이브러리에서 제공하는 useQuery hook는 api 호출의 과정을 간략화 해줄 뿐만 아니라, 캐싱을 이용해 api호출의 빈도를 최소화한다.
useQuery를 사용하기 이전에 api를 호출하려면 다음과 같이 코드를 작성해야 했다.
const [loading, setLoading] = useState(true); const { coinId } = useParams<RouteParams>(); const [info, setInfo] = useState<InfoData>(); const [priceInfo, setPriceInfo] = useState<PriceData>(); useEffect(() => { (async () => { const infoData = await ( await fetch(`https://api.coinpaprika.com/v1/coins/${coinId}`) ).json(); const priceData = await ( await fetch(`https://api.coinpaprika.com/v1/tickers/${coinId}`) ).json(); console.log(infoData, priceData); setInfo(infoData); setPriceInfo(priceData); setLoading(false); })(); }, [coinId]);
하지만, useQuery를 사용하면 다음과 같이 간략해진다
const { coinId } = useParams<RouteParams>(); const { isLoading: infoLoading, data: infoData } = useQuery<InfoData>( ["info", coinId], () => fetchCoinInfo(coinId) ); const { isLoading: tickersLoading, data: tickersData } = useQuery<TickersData>(["tickers", coinId], () => fetchCoinTickers(coinId), { refetchInterval: 5000, // *refetch* notifyOnChangeProps: ["data"], }); const loading = infoLoading || tickersLoading;
const BASE_URL = `https://api.coinpaprika.com/v1`; export async function fetchCoinInfo(coinId: string) { const response = await fetch(`${BASE_URL}/coins/${coinId}`); const json = await response.json(); return json; } export function fetchCoinTickers(coinId: string) { return fetch(`${BASE_URL}/tickers/${coinId}`).then((response) => response.json()); }
useEffect, useState를 사용하지 않을 수 있을 뿐더러, 자체적으로 로딩을 알려주도록 isLoading이라는 반환값도 있어서 처리하기 쉬워진다.
다른 이점도 있는데, 바로 캐싱이다.
캐싱을 이용하면 이미 캐시되어 있는 데이터는 api를 호출하지 않기 때문에 페이지를 불러올 때 로딩이 없어질 뿐더러, 서버에 부담도 줄어든다.
뿐만 아니라, fetching의 주기를 개발자 맘대로 지정해 줄 수 있다.
위 코드의 *refetch* 주석을 살펴보면 인터벌로 5000ms를 주는데 즉 5초마다 해당 api를 호출하도록 하여 나름 실시간같은 서비스를 제공할 수 있도록 도와준다.
단점은, api를 다시 호출할 때 마다 페이지가 새로고침되어 (눈으로 보이진 않지만, 선택된 것이 초기화 된다던가.. 차트 api로 그린 차트가 확대가 초기화 된다든가...) 사용자 경험을 해칠 수 있다는 사실이다.
내 경우는 notifyOnChangeProps: "data" 를 추가해 data의 변화가 일어날 때만, 페이지가 새로고침 되도록 조절했는데, 더 나은 방법이 있으면 추가로 포스팅 하겠다.
마지막으로 react-query에서 제공하는 개발자 툴을 이용할 수 있는데, App.tsx에 <ReactQueryDevtools initiallsOpen={true} /> 태그를 넣음으로서 실시간으로 캐싱되고 있는 api 데이터를 확인할 수 있다.
<Fig. 1> 하단에 있는 것이 바로 ReactQueryDevtools 이다.
더 많은 정보는 아래 링크에서 확인할 수 있다.
요약
function useGroups() { return useQuery<Group[], Error>('groups', fetchGroups) }
'FW, Lib 공부 > React' 카테고리의 다른 글
useLocation() (0) 2022.06.22 useParams() (0) 2022.06.22 React 프로젝트 기본 세팅 (0) 2022.06.22 ts 타입 정리 (0) 2022.06.20 useEffect() (0) 2022.05.23