요번한주를 개인적으로 정리하는 글입니다
React-Query 알아보기 및 사용하기
리액트 쿼리란?
React Query 는 종종 React에 대한 누락된 데이터 가져오기 라이브러리로 설명이됩니다만 기술적인 용어로 말하면 React 애플리케이션에서 서버상태 가져오기, 캐싱 , 동기화 및 업데이트를 쉽게만듭니다
만들어진 동기
- React 애플리케이션에는 구성 요소에서 데이터를 가져오거나 업데이타흐난 독창적인 방법이 제공되지않으므로 개발자는 데이터를 가져오는 고유한 방법을 구축해야함
- 대부분의 기존 상태 관리 라이브러리는 클라이언트 상태 작업에 적합하지만 비동기 또는 상태 작업에는 그다지 좋지않음 ( 서버의 상태가 완전히 다르기 때문 )
- 서버 데이터는 항상 최신 상태임을 보장하지않음 ( fetching 을 수행해야만 최신 데이터로 전환됨 )
- 네트워크 통신은 최소한으로 줄이는게 좋은데 복수의 컴포넌트에서 최신데이터를 가져오기 위해 fetching을 여러번 수행하는 낭비가 발생할수있음
react 에서 비동기를 다루는 방법은 다양합니다
JavaScript 언어이니 당연히 Promise, async & await 으로 처리가 가능합니다
redux 를 사용하고 있다면 redux saga , thunk 등 다양한 미들웨어가 제공됩니다
하지만 이러한 방법들을 사용한다면 서버의 상태를 관리하기가 어려운일이라고 합니다
서버의 상태란
- 제어하거나 소유하지 않는 위치에 원격으로 유지됨
- 가져오기 및 업데이트를 위한 비동기 API 필요
- 공유 소유권을 의미하며 사용자 모르게 다른 사람이 변경할 수 있음
- 주의하지 않으면 애플리케이션이 잠재적으로 오래된 상태가 될수 있음
React query 에서 제공하는 것
- 캐싱 ( stale, inactive )
- 서버 데이터 중복 요청 제거
- 만료된 데이터를 백그라운드 상태에서의 업데이트
- 데이터의 유효시간을 설정하고 유효 시간이 지난 것을 아는것
- 병렬적 요청 수행
- 서버상태이 메모리 관리 및 가비지 콜렉션
- 페이지네이션 , lazy loading 의 성능 최적화
- 편리한 디버깅 툴
- SSR, Next.js 지원
이러한 기능들이 없어도 앱을 구현할수는 있습니다
하지만 높은 품질의 앱을 위해서는 필요한작업이라 할 수 있습니다
React Query 는 위와 같은 기능을 사용할 수 있도록 도와줍니다
React Query 사용해보기
yarn create react-app my_react_query
cd my_react_query
yarn add react-query


캐시를 관리하기위하여 QueryClient 를 변수에 담아 만들어둡니다
QueryClientProvider 로 감싸 QueryClientProvider 안의 모든 것에 queryClient에 접근할수있도록 감싸줍니다
React Query 에서 가장 환영받는 부분 중 하나는 전용 devtools 세트와 함께 제공된다는 것입니다
React Query 의 devtools를 사용하려면 다음을 연결해줘야합니다
import { ReactQueryDevtools } from "react-query/devtools";
function App() {
return (
<>
<GlobalStyle />
<Router />
<ReactQueryDevtools initialIsOpen={true} />
</>
);
React Query devtools 사용 화면

React Query 사용법
React Query 를 통해 관리하는 쿼리 데이터 ( Query, useQuery 가 반환하는 객체 속성값 ) 는 4가지 상태를 가집니다
fetching -> fresh -> stale -> inactive -> delete
- fetching : 데이터 요청하는 상태인 쿼리
- fresh : 데이터가 프레시한 ( 만료되지 않은 ) 상태
- 컴포넌트의 상태가 변경되더라도 데이터를 다시 요청 하지 않는다
- 새로고침 하면 다시 fetching 한다
- stale : 데이터가 만료된 상태
- 데이터가 만료되었다는 것은 서버에서 한번 프론트( 클라이언트 )로 데이터를 주면 그 사이에 다른 유저가 데이터를 추가 , 수정 , 삭제 등등 할수 있기떄문에 만료되었다고 한다 ( 최신화가 필요한 데이터 )
- 컴포넌트가 마운트 , 업데이트되면 데이터를 다시 요청합니다
- fresh 에서 stale 로 넘어가는 시간 -> 기본값 0
- inactive : 사용하지 않는 상태
- 일정 시간이 지나면 가비지 콜렉터가 캐시에서 제거함
- 기본값 5분
-delete : 가비지 콜렉터에 의하여 캐시에서 제거된 커리
React Query 는 데이터 패칭, 데이터 동기화 , 데이터 업데이트 , 데이터 캐싱을 도와주고 두개의 훅과 하나의 유틸리티 함수로 작성할 코드 양을 줄여줍니다
React Query 사용 전 코드
const [coins, setCoins] = useState<CoinInterface[]>([]);
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);
})();
}, []);
위의 useState<CoinInterface[]> 는 TypeScript 로 사용되어 추가된 부분
React Query 사용 후 코드
const { isLoading, data } = useQuery<ICoin[]>("allCoins", fetchCoins);
위의 useQuery<ICoin[]> 는 TypeScript 로 사용되어 추가된 부분
React Query 를 사용하기위해서 첫 단계로 fetcher 함수를 만들어 줘야합니다
기존에는 useEffect 에서 사용하여
async () => {
const response = await fetch("https://api.coinpaprika.com/v1/coins");
const json = await response.json();
}
위와같이 사용해줬지만
export async function fetchCoins() {
const response = await fetch(`https://api.coinpaprika.com/v1/coins/${coinId}`)
const json = await response.json();
return json;
}
위 fetcher함수는 json data ( json data Promise )를 return 해줘야함
위와같이 변경하여 redux에서 따로 빼서 공통으로 관리하듯 Api 파일에 위 코드를 만들어 사용합니다
const {isLoading, data} = useQuery("allCoins", fetchCoins)
위 코드에 대한 설명입니다
1. api.ts의 fetcher 함수를 불러오기위해 임포트를 해줘 fetchCoins를 사용하게해줍니다
2. uswQuery 라는 훅을 react-query 에서 임포트하여 사용할 준비를함
- useQuery는 2가지 argment를 필요로함
- queryKey = query의 고유 식별자
- fetch 함수 = api.ts 에다 만든 fetchCoins 함수
3. React Query 의 옵션중 isLoading 값을 사용합니다
- React Query 의 옵션중 isLoading 는 boolean 값을 반환함( 전에 사용되던 코드에서 loading 및 setLoading 등을 데체 가능함 )
4. useQuery는 키와 데이터를 불러오는 비동기 함수를 인자로 받아 어플리케이션의 현재 상태를 나타내는 다양한 값을 반환합니다
- useQuery 훅은 argment의 2번째인자에 작성된 fetcher( fetchCoins ) 함수를 부른다
- fetcher함수가 loading 중이라면 react query 는 여기서 fetching {isloading} 로 진행중으로 알려준다
- fetcher 함수가 끝나면 fetcher 함수에서 반환되는 json 값을 data 에 넣어준다
- 처음 로딩시에 데이터를 가져오는동안 loading 가 보이고 로딩 완료시 데이터가 보이며 데이터는 캐시에 저장된다
- 데이터가 업데이트 ( 변화 ) 되지 않은 상태에서 전화면으로 이동후 같은 데이터로 접속시 loading이 되지않고 저장되어있는 캐시에서 불러와 데이터를 보여준다
- 리액트 쿼리는 데이터를 유지하고있는다 ( 리액트 쿼리는 api로부터 데이터를 ( reponse ) 받아 캐싱( 저장 ) 함
'프로그램 시작후 각 주차 정리' 카테고리의 다른 글
| 공부 13주차 - part 2 ( React-Hook- Form ) (0) | 2022.06.05 |
|---|---|
| 공부 13주차 - part 1 ( ApexCharts , Recoil ) (0) | 2022.06.04 |
| 공부 11주차 (0) | 2022.05.22 |
| 공부 10주차 (0) | 2022.05.15 |
| 공부 9주차 (0) | 2022.05.07 |