React Query
: 웹 애플리케이션에서 서버 상태 가져오기, 캐싱, 동기화 및 업데이트를 매우 쉽게 만드는 상태관리 라이브러리.
캐싱
자주 필요한 데이터나 값의 복사본을 일시적으로 저장, 보관하기 위해 사용하는 곳을 캐시라고 하고 이 캐시를 사용하는 것을 캐싱이라고한다. 리액트 쿼리에서는 이 캐싱 기능을 지원한다. 캐시에 데이터를 저장하여 일반 fetch axios를 사용했을때와 달리 한번 로딩 후 다시 들어가도 저장되어 있는 캐시가 있어 로딩없이 데이터가 보인다.
동일한 데이터에 대한 중복 요청을 단일 요청으로 통합
백그라운드에서 오래된 데이터 업데이트
데이터가 얼마나 오래되었는지 알수 있다.
데이터 업데이트를 가능한 빠르게 반영
페이지네이션 및 데이터 지연 로드와 같은 성능 최적화
서버 상태의 메모리 및 가비지 수집 관리
구조공유를 사용하여 쿼리결과를 메모화
$ npm i @tanstack/react-query
# or
$ pnpm add @tanstack/react-query
# or
$ yarn add @tanstack/react-query
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
const root = ReactDOM.createRoot(document.getElementById('root'));
const queryClient = new QueryClient();
root.render(<QueryClientProvider client={queryClient}>
<BrowserRouter>
<App />
<ReactQueryDevtools initialIsOpen={false} buttonPosition='bottom-right' />
</BrowserRouter>
</QueryClientProvider>
);
*라우터사용시 브라우저라우터는 리액트쿼리안에서 선언해주기.
// 필수옵션
const query =useQuery({
queryKey:['posts'], // 해당 api호출은 post라는 이름을 가진다.
queryFn:fetchPost, // api호출 함수를 넣어준다.
})
// 필수+선택옵션
const {data, isLoading, isError, error, refetch}=useQuery({
// 각각의 유니크란 이름을 지어줌
queryKey:['posts'], // 해당 api호출이름은 posts다
queryFn:fetchPost,
retry:1, //에러시 몇시시도할것인지?
select:(data)=>{
return data.data //우리가 받은 데이터의 데이터필드만 뽑아와주세요 ㅎㅎ
},
gcTime:5000, //5초주기로 캐시가 비워짐(gcTime은 v5에서만 사용. 하위버전은 cacheTime이라고함)
staleTime:10000, //staleTime이 아무리 길어도 캐시가 비워지면 다시호출(staleTime < gcTime)캐시가더오래살아있어야의미가있다.
// refetchInterval:3000, api를 3000초마다 호출
// refetchOnMount:false 컴포넌트 들어갈때마다(true) api부를건지 한번만부를건지(false) 기본값은 true
// refetchOnWindowFocus:true window에 포커스시 api호출(유저는 항상 fresh한 데이터를 볼수있음)
// enabled: false //처음부터 api호출 못하게함(false) 사용예)키워드검색시 data api호출(true,false고정이아니라 다양한조건을 넣어줄수있다.)기본값은 true
})
-src폴더 안에 하위폴더 hooks생성
-hooks폴더안에 useQuery사용할파일생성
// usePosts.js
import {useQuery} from '@tanstack/react-query'
import axios from 'axios'
const fetchPost=(postId)=>{
return axios.get(dataUrl)
}
export const usePostQuery=()=>{
return useQuery({
// 각각의 유니크란 이름을 지어줌
queryKey:['posts',postId], // 해당 api호출이름은 posts다
queryFn:()=>fetchPost(postId),
retry:1, //에러시 몇시시도할것인지?
select:(data)=>{
return data.data //우리가 받은 데이터의 데이터필드만 뽑아와주세요 ㅎㅎ
},
gcTime:5000, //5초주기로 캐시가 비워짐(gcTime은 v5에서만 사용. 하위버전은 cacheTime이라고함)
staleTime:10000, //staleTime이 아무리 길어도 캐시가 비워지면 다시호출(staleTime < gcTime)캐시가더오래살아있어야의미가있다.
// refetchInterval:3000, api를 3000초마다 호출
// refetchOnMount:false 컴포넌트 들어갈때마다(true) api부를건지 한번만부를건지(false) 기본값은 true
// refetchOnWindowFocus:true window에 포커스시 api호출(유저는 항상 fresh한 데이터를 볼수있음)
// enabled: false //처음부터 api호출 못하게함(false) 사용예)키워드검색시 data api호출(true,false고정이아니라 다양한조건을 넣어줄수있다.)기본값은 true
})
}
-UI
// ReactQueryPage.jsx
import { usePostQuery } from './hooks/usePosts'
export default function ReactQueryPage(){
const {data, isLoading, isError, error, refetch} = usePostQuery()
if(isLoading){
return <h1>Loading...</h1>
}
if(isError){
return <h1>error</h1>
}
return(
<div>
{data?data.map((a)=><div>{a.title}</div>):null}
{/* 버튼을 누를때마다 api호출 (refetch기능)*/}
<button onClick={refetch}>api호출</button>
</div>
)
}