From ac292bcf2a4a5f189bba7bfc322cb060e4fbe3dc Mon Sep 17 00:00:00 2001 From: "jihoon87.lee" Date: Wed, 4 Feb 2026 09:34:54 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20React=20Query=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A3=A8=ED=8A=B8=20=EB=A0=88=EC=9D=B4=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - QueryProvider 컴포넌트 생성 - React Query DevTools 추가 - 루트 레이아웃에 QueryProvider 래핑 --- app/layout.tsx | 3 ++- providers/query-provider.tsx | 47 ++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 providers/query-provider.tsx diff --git a/app/layout.tsx b/app/layout.tsx index f7fa87e..ded5050 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,6 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; +import { QueryProvider } from "@/providers/query-provider"; import "./globals.css"; const geistSans = Geist({ @@ -27,7 +28,7 @@ export default function RootLayout({ - {children} + {children} ); diff --git a/providers/query-provider.tsx b/providers/query-provider.tsx new file mode 100644 index 0000000..ebdb123 --- /dev/null +++ b/providers/query-provider.tsx @@ -0,0 +1,47 @@ +"use client"; + +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; +import { useState } from "react"; + +/** + * [React Query Provider] + * + * 애플리케이션 전역에 React Query 기능을 제공합니다. + * - 서버 상태 관리 + * - 자동 캐싱 및 재검증 + * - 로딩/에러 상태 관리 + * - DevTools 통합 (개발 환경) + * + * @see https://tanstack.com/query/latest + */ +export function QueryProvider({ children }: { children: React.ReactNode }) { + // ========== QueryClient 생성 ========== + // useState로 감싸서 리렌더링 시에도 동일한 인스턴스 유지 + const [queryClient] = useState( + () => + new QueryClient({ + defaultOptions: { + queries: { + // ========== 쿼리 기본 옵션 ========== + staleTime: 60 * 1000, // 1분 - 데이터가 신선한 것으로 간주되는 시간 + gcTime: 5 * 60 * 1000, // 5분 - 캐시 유지 시간 (이전 cacheTime) + retry: 1, // 실패 시 재시도 횟수 + refetchOnWindowFocus: false, // 윈도우 포커스 시 자동 재검증 비활성화 + }, + mutations: { + // ========== Mutation 기본 옵션 ========== + retry: 0, // Mutation은 재시도하지 않음 + }, + }, + }), + ); + + return ( + + {children} + {/* ========== DevTools (개발 환경에서만 표시) ========== */} + + + ); +}