
Next에 React Query 적용하기
- npm i @tanstack/react-query@5 로 설치
- npm i @tanstack/react-query-devtools@5 -D
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import React, { ReactNode, useState } from "react";
type RQProviderProps = {
children: ReactNode;
};
const RQProvider = ({ children }: RQProviderProps) => {
const [client] = useState(
new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: false,
},
},
})
);
return (
<QueryClientProvider client={client}>
{children}
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
};
export default RQProvider;
layout.tsx에서 감싸주기 (tip: 넓게 감싸라)
<RQProvider>
<main className="flex flex-col flex-1 w-full max-w-screen-xl h-full">
<Header />
{children}
<Footer />
</main>
</RQProvider>
React Query 사용 법
async function 함수() {
const res = await fetch('url',
next: {
tags: ['posts','recommends'],
},
cache: 'no-store'
)
if(!res.ok){
throw new Error
}
return res.json();
}
const queryClient = new QueryClient(
)
await queryClient.prefecthQuery({
queryKey: ['posts', 'recommends'], queryFn : 함수
})
queryClient.getQueryData(['posts','recommends'])
const dehydratedState = dehydate(queryClient)
<HydrationBoundary state={dehydrateState}>
</HydrationBoundary>
'use client'
import {useQuery} ...
export default function Page() {
const {data} = useQuery({ queryKey : ['posts', 'recommends'], queryFn : 함수명})
return data.map((post) =>(
<Post key={post.postId} post={post} />
))
}
RQ를 쓰면 좋은 이유와 상태
- Redux와의 차이?
- Redux → 컴포넌트간 데이터 공유! but 캐싱 약함..
- RQ → 데이터를 서버로부터 가져오는 것 + 캐싱 (트래픽 관리, 사용자 경험)
- RQ도 물론 컴포넌트간 데이터 공유도 가능하니 훨씬 편하지!
- 로딩, 성공, 실패 상태에대한 쉬운 사용
- queryKey라는 키 관리 시스템
- 데이터의 상태
- Fresh → 업데이트할 필요 없는 최신 상태
- Fresh의 상태 설정은 개발자가 한다 (기본값은 0초)
- staleTime으로 설정, Infinity or ms단위
- Fresh상태에선 캐시에서 값을 가져옴
- gcTime : 기본 5분, 데이터를 얼마나 가지고 있을 것인가 (캐시가 날라감)
- staletime은 반드시 gcTime보다 작아야 한다
- Stale → 업데이트가 필요한 데이터 (상한 상태)
- 언제?
- refetchOnWindowFoucs (윈도우 포커스 될때)
- retryOnMound (컴포넌트가 다시 마운트 될때, 페이지 다시 접속할때)
- refetchOnReconnect (인터넷 연결이 끊겼다가 다시 접속됐을때)
- retry (데이터 가져오기 실패시 재시도 여부)
- fetching → 데이터를 가져올때
- paused → 데이터를 가져오는걸 잠시 멈출때 (인터넷 끊김 등)
- Actions
- Refetch → 데이터 새로 가져오기 (무조건), 해당 데이터를 사용하지 않는 페이지에서도 가져옴 (즉 B에서 필요한 데이터가있을때 A페이지에 있어도 데이터를 가져와 캐시에 저장)
- Invalidate → Refecth와 유사함, 단, 현재 데이터를 사용하는 페이지에 접속해 있는 경우에만 가져옴 (즉 A페이지에서 Invalidate를 하면 데이터는 캐시에 없는 상태, B페이지로 이동하면 데이터를 가져옴)
- Reset → initailData (초기 데이터)가 있는 경우 초기데이터로 초기화
- Remove → 쿼리키 제거
- Restore Loading → 로딩 상태로 바꿈
- Trigger Error → Error 상태로 바꿔줌