Skip to Content
API 레퍼런스HooksuseNexusQuery

useNexusQuery

useNexusQuerydefinition으로 정의된 데이터를 클라이언트에서 가져오고, 캐시하고, 재검증하기 위한 훅입니다. 클라이언트 컴포넌트에서 데이터를 읽기 위해 설계되었습니다.

Import

import { useNexusQuery } from 'next-nexus/client';

시그니처 (Signature)

useNexusQuery<TData, TSelectedData = TData>( definition: NexusDefinition<TData>, options?: { ... } ): { data: TSelectedData | undefined headers: Headers | undefined error: Error | null isPending: boolean isPendingBackground: boolean isSuccess: boolean isError: boolean revalidate: () => Promise<void> }
  • definition: GET 메서드를 사용하는 definition 객체. GET이 아닌 definition이 전달되면 오류가 발생합니다.
  • options: 훅의 동작을 설정하는 객체. 아래 Options를 참고하세요.

핵심 개념 (Core Concepts)

하이드레이션 인식 페칭 (Hydration-Aware Fetching)

useNexusQuery는 서버에서 페치되어 하이드레이션으로 클라이언트에 전달된 데이터를 인식합니다. 마운트 시점에 클라이언트 캐시에 데이터가 있으면, 새로운 요청 없이 즉시 렌더링하여 UI 깜빡임을 제거합니다.

Foreground/Background 재검증

revalidate() 함수가 호출되거나 마운트, 창 포커스 등 자동 재검증 이벤트가 발생할 때 훅이 자동으로 재검증 모드를 결정합니다.

  • Foreground: 캐시된 데이터가 없거나, keepStaleDatafalse이고 데이터가 만료(stale)된 경우. 이 때 isPendingtrue가 됩니다.
  • Background: 만료된 데이터가 있고 keepStaleDatatrue(기본값)인 경우. 이 때 isPendingfalse인 채로 isPendingBackgroundtrue가 됩니다.
  • 실행 안 함 (No-op): 신선한(fresh) 데이터가 있으면 요청을 수행하지 않습니다.

상태 플래그와 UX (State Flags and UX)

  • isPending: Foreground 재검증 중에 true가 됩니다. 아직 데이터가 없을 때(isPending && !data) 스피너와 같은 로딩 상태를 표시하는 데 사용하세요.
  • isPendingBackground: Background 재검증 중에 true가 됩니다. 만료된 데이터를 화면에 계속 보여주면서, ‘새로고침’ 버튼을 비활성화하는 등 미묘한 로딩 표시를 위해 사용하세요.

Options

  • route?: string - 요청을 Next.js 라우트 핸들러로 프록시합니다. 이 옵션이 제공되면 런타임은 definitionbaseURL을 지우고 route를 유효 엔드포인트로 사용합니다.
  • enabled?: boolean (기본값: true) - false로 설정하면 훅이 데이터를 가져오거나 캐시 업데이트를 구독하지 않습니다.
  • select?: (data: TData) => TSelectedData - 데이터를 선택하거나 변환하는 함수. 선택된 값이 변경될 때만 컴포넌트가 리렌더링됩니다.
  • revalidateOnWindowFocus?: boolean (기본값: true) - 창이 다시 포커스될 때 자동으로 재검증합니다.
  • revalidateOnMount?: boolean (기본값: true) - 데이터가 만료 상태일 때 마운트 시 자동으로 재검증합니다.
  • keepStaleData?: boolean (기본값: true) - true이면 Background 재검증이 발생하는 동안 만료된 데이터가 화면에 유지됩니다. false이면 Foreground 재검증 중에 dataundefined가 됩니다.

예제 (Examples)

기본 사용법

'use client'; import { useNexusQuery } from 'next-nexus/client'; import { productDefinition } from '@/api/productDefinition'; export function ProductListClient() { const { data, isPending } = useNexusQuery(productDefinition.list); if (isPending && !data) return <div>로딩 중...</div>; const products = data ?? []; return ( <ul> {products.map(p => ( <li key={p.id}>{p.name}</li> ))} </ul> ); }

select 옵션 사용하기

'use client'; import { useNexusQuery } from 'next-nexus/client'; import { statsDefinition } from '@/api/statsDefinition'; export function TotalCount() { const { data: count } = useNexusQuery(statsDefinition.summary, { select: s => s.total, }); return <div>총계: {count ?? 0}</div>; }

route 오버라이드 사용하기

'use client'; import { useNexusQuery } from 'next-nexus/client'; import { productDefinition } from '@/api/productDefinition'; export function ProductListViaRoute() { const { data } = useNexusQuery(productDefinition.list, { route: '/api/products' }); return <div>{data?.length ?? 0}개 항목</div>; }

캐시된 헤더 읽기

'use client'; import { useNexusQuery } from 'next-nexus/client'; import { listWithTotalDefinition } from '@/api/productDefinition'; // 이 definition이 있다고 가정 export function ProductListWithTotal() { const { data, headers } = useNexusQuery(listWithTotalDefinition); const total = headers?.get('x-total-count'); return ( <div> 항목: {data?.length ?? 0} / 전체: {total ?? 'n/a'} </div> ); }

함께 보기

Last updated on