React & Library/React-Query

[React / React Query] React Query를 사용하게 되면서 좋은 점들

yoonjong Park 2022. 12. 21.

React Query

공식문서에는 아래와 같이 설명되어 있다.

Performant and powerful data synchronization for React

음... 그래. 리액트에 어울리는 동기화 라이브러리 라고 한다. (그래? 한번 써보았다.)

 

기존 코드

import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";
import { getCoins } from "APIs/get";
import { useQuery } from "react-query";

// 
 Styled Component 생략 
//

const Coins = () => {
  const { isLoading, data } = useQuery<ICoin[]>("allCoins", getCoins, {
    select: data => data.slice(0, 30),
  });

  // 아래 주석 처리된 부분이 모두 위에 것으로 변경되었다.
  // const [coins, setCoins] = useState<CoinInterface[]>([]);
  // const [loading, setLoading] = useState(true);
  // useEffect(() => {
  //   (async () => {
  //     const _cutCoins = await getCoins();
  //     setCoins(_cutCoins);
  //     setLoading(false);
  //   })();
  // }, []);

  return (
    <Container>
      <Header>
        <Title>Coin list</Title>
      </Header>
      {isLoading ? (
        <Loader>loading...</Loader>
      ) : (
        <CoinsList>
          {data?.map(coin => (
            <Coin key={coin.id}>
              <Link to={`/${coin.id}`} state={{ name: coin.name }}>
                <Img
                  src={`https://coinicons-api.vercel.app/api/icon/${coin.symbol.toLocaleLowerCase()}`}
                />
                <Text>{coin.name} &rarr;</Text>
              </Link>
            </Coin>
          ))}
        </CoinsList>
      )}
    </Container>
  );
};

export default Coins;

눈여겨 볼 점

  const { isLoading, data } = useQuery<ICoin[]>("allCoins", getCoins, {
    select: data => data.slice(0, 30),
  });

isLoading

API 로딩 중 boolean type data

data

return 받은 API data (*json Type으로 넘겨주는 것이 일반적(권장, 필수아님))

"allCoins"

Query-key 로 전체 프로젝트에 같은 이름이 있으면 안됨.

getCoins

API call Function Name

*원칙적인 사용은 아래와 같은데, 위와 같이 축약해서 사용하는 것이다.

  const { isLoading, error, data } = useQuery({
    queryKey: ['repoData'],
    queryFn: () =>
      fetch('https://api.github.com/repos/tanstack/query').then(res =>
        res.json()
      )
  })

 

 

장점

1. React-Query가 적용된 API는 cache 되는 것을 볼 수 있다. 불필요한 API호출이 없어진다.

여기서 질문이 생긴다. 그럼 저장되는 Data는 어디에 보관되는 걸까? 잘 모르겠다.
내가 확인한 바로는, Recoil 처럼 Browser 내 Storage를 사용하는 것은 아닌 것 같다.

이 부분을 확인하려 공식문서를 찾아봤다. 흠... 첫 문장부터 답이 나온다. 어딘가에 숨겨두고 있는 것으로 추정된다.

  • Is persisted remotely in a location you do not control or own
  • Requires asynchronous APIs for fetching and updating
  • Implies shared ownership and can be changed by other people without your knowledge
  • Can potentially become "out of date" in your applications if you're not careful
  • 귀하가 통제하거나 소유하지 않는 위치에 원격으로 유지됩니다.
  • 가져오기 및 업데이트를 위한 비동기 API가 필요합니다.
  • 공유 소유권을 암시하며 사용자 모르게 다른 사람이 변경할 수 있음
  • 주의하지 않으면 응용 프로그램에서 잠재적으로 "구식"이 될 수 있습니다.

disk cache 라고 나오면서, API호출 진행하지 않는 것을 알 수 있다.

단점

아직 못찼았다.

 

기타 특징

useQueries

useQuery 말고 useQueries 라는 것도 있다. 

Promise.all 하고 비슷하게 동작한다. 배열로 useQuery 실행 결과 값들을 리턴해준다. (병렬 비동기 처리를 하기 위해 사용)

보통 api 호출 값이니까 isLoading, data,... 등등을 배열로 묶어서 받게 된다고 보면된다.

그러나, 과연 좋은지는 의문이다.

노마드코더 니코 같은 경우는, useQuery를 2개 사용하고, 각 loading 값을 아래와 같이 선언해서 단축평가를 받도록 처리했다.

const isLoading = infoLoading || tickersLoading;

내가 보기에도 오히려 이 방식이 더 적합해보인다.

참고2. 에서는 동적 렌더링이 필요할 때만, useQueries를 사용하는 것을 권장했다. (이건, 필요한 API 연동 포인트가 있을 때 좀 더 고민해 봐야겠다.

 

 

 

추가로 더 작업하면서 알게되는 내용은 추가하도록 한다.

 

참고

1.  https://react-query-v3.tanstack.com/overview#motivation

 

Overview | TanStack Query Docs

React Query is often described as the missing data-fetching library for React, but in more technical terms, it makes fetching, caching, synchronizing and updating server state in your React applications a breeze. Motivation

tanstack.com

2. https://jforj.tistory.com/245

 

[React] React Query의 useQueries에 대해 알아보기

안녕하세요. J4J입니다. 이번 포스팅은 React Query의 useQueries에 대해 적어보는 시간을 가져보려고 합니다. useQueries란? useQueries는 React Query에서 useQuery의 동적 병렬 쿼리 작업을 위해 사용됩니다. 그

jforj.tistory.com

 

댓글