[Next.js] Next에서 React Query 적용하기

insung·2024년 6월 20일

Nextjs

목록 보기
15/21

Next에 React Query 적용하기

  • npm i @tanstack/react-query@5 로 설치
  • npm i @tanstack/react-query-devtools@5 -D
    • RQProvider.tsx 작성
"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 사용 법

// server componet에서 사용하기
async function 함수() {
	 const res = await fetch('url',
	 next: {
		 tags: ['posts','recommends'], // next에서만 지원하는 태그, 캐싱을 도와줌
	 },
	 cache: 'no-store' // 기본값은 저장, no-store 명시해주면 캐싱하지 않는다
	 )
	 
	 if(!res.ok){
	 throw new Error
	 }
	 
	 
	 // revalidateTag("recommends") // 서버에 있는 캐시 날려주기 함수 
	 // revalidatePath("/home") // 경로와 관련된 모든 요청들을 새로고침 해줌 
	 
	 
	 return res.json();
	 
}

const queryClient = new QueryClient(
)
await queryClient.prefecthQuery({
queryKey: ['posts', 'recommends'], queryFn : 함수
})

queryClient.getQueryData(['posts','recommends'])

const dehydratedState = dehydate(queryClient) // ssr 에서 쓰려면 dehydrate 해줘야함

<HydrationBoundary state={dehydrateState}>
</HydrationBoundary>
// client componet에서 사용하기

'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 상태로 바꿔줌
profile
안녕하세요 프론트엔드 관련 포스팅을 주로 하고 있습니다

0개의 댓글