92.React Query

조연정·2021년 12월 21일
1

리액트 쿼리를 사용해서 server와의 비동기 로직코드를 줄여보자.

React Query?

state를 관리하는 라이브러리로 server와 client 사이의 비동기 로직들을 쉽게 만들어주는 도구이다.

그래서 React Query를 사용하면 뭐가 좋은데?

첫번째, 일련의 코드를 확 줄여준다.
데이터를 가져오기 위한 일련의 필수적인 코드들이 있다.
예를들어, 서버와 통신하기 위해서 fetch함수를 만들고, 받아온 데이터를 담을 state를 만들어주고, 받아오는 상태에 따라 loading 화면을 보여주기 위해 state를 만들고 세팅해주는 등의 세트 코드들이 있다. 하지만, react query와 함께라면 코드를 획기적으로 줄일 수 있다.
두번째, 데이터를 캐시에 저장해둔다.
전형적인 기존 코드를 사용했다면 뒤로가기를 눌렀을 때 loading화면이 보이지만,
react-query 사용 시 로딩이 보이지 않는다. api를 다시 불러오는 행동을 하지 않고, api로부터 받아온 response를 캐싱해두기 때문이다.

사용방법

//index.tsx
import { QueryClient } from 'react-query';

// client 생성 
const queryClient = new QueryClient();

ReactDOM.render(
  <React.StrictMode>
  //Provider 생성, props로 client 필요
    <QueryClientProvider client={queryClient}>
      <ThemeProvider theme={theme}>
        <App />
      </ThemeProvider>
    </QueryClientProvider>
  </React.StrictMode>,
  document.getElementById('root'),
);

QueryClientProvider 안에 있는 모든 것은 쿼리 클라이언트에 접근할 수 있다.

react query 사용 전 코드
// app.tsx
  const [info, setInfo] = useState<IInfo[]>([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    (async () => {
      const response = await fetch('https://api.com/information');
      const json = await response.json();
      setInfo(json.slice(0, 100));
      setLoading(false);
    })();
  }, []);
...
{loading ? (
        <div>Loading...</div>
      ) : (
        <Wrapper>
          {info.map((item) => (
            <Card key={item.id}/>         
          ))}
        </Wrapper>
      )}
 ...      
react query 사용 후 코드
// api.ts
export const fetchData = () => {
  return fetch('https://api.com/information').then((res) => res.json());
};

// app.tsx
  const {isLoading, data} = useQuery<IInfo>('allInfo', fetchData);

...
{isLoading ? (
        <div>Loading...</div>
      ) : (
        <Wrapper>
          {data?.map((item) => (
            <Card key={item.id}/>         
          ))}
        </Wrapper>
      )}
 ...      

useQuery는 두 가지의 인자를 받는데, 첫번째는 queryKey(고유식별자), fetcher함수이다.

위에서 말했듯이, react query를 사용 후 코드가 줄어들었다. 필요한 요소들은 useQuery가 return하는 것에서 받아올 수 있다.
useQuery는 fetch함수(fetchData)를 불러오고 함수가 isLoading이면, true
함수가 끝나면, false를 알려준다.
또한, fetcher함수가 끝나면, 데이터를 data에 넣어준다.

*queryKey 같은 값을 갖는 경우

queryKey는 앞서말했듯이 고유한 이름을 가져야 한다. 퀴리키가 겹치는 경우에는 고유한 이름을 갖도록 바꿔줘야 한다.
useQuery는 쿼리키를 배열로 취급하기 때문에 아래 예시와 같이 배열 안에 고유한 이름을 추가해준다.

*2개 이상의 useQuery hook사용할 경우

useQuery를 2개 이상 사용할 경우 isLoading,data 등의 리턴값들이 2개 이상이 된다. 이름이 중복되면 안되기 때문에 아래와 같이 이름을 따로 설정해야 한다.

//api.ts

export const fetchInfoData = (Id: string) => {
  return fetch(`https://api.com/'${Id}`).then((res) => res.json());
};

//app.tsx
const { Id } = useParams<{ Id: string }>();
const { isLoading: infoLoading, data: infoData } = useQuery<IInfo>(
    ['info', Id],
    () => fetchCoinInfo(Id),
  );
  const { isLoading: productLoading, data: productData } = useQuery<IProduct>(
    ['product', Id],
    () => fetchCoinTickers(Id),
  );
const loading = infoLoading || productLoading;
...
{loading ? (
        <div>Loading...</div>
      ) : (
        <>
        	<span>{infoData.name}</span>
        	<span>{productData.price}</span>
        </>
      )};
...
profile
Lv.1🌷

0개의 댓글