UNPKG

next-unified-query

Version:

React hooks and components for next-unified-query-core

211 lines (206 loc) 10.3 kB
import * as next_unified_query_core from 'next-unified-query-core'; import { FetchError, QueryConfig, ZodType, FetchConfig, ExtractParams, QueryObserverResult, ExtractQueryData, ApiErrorResponse, InferIfZodSchema, RequestConfig, HttpMethod, NextTypeFetch, z, MutationConfig, QueryClient, QueryClientOptionsWithInterceptors, QueryState } from 'next-unified-query-core'; import React$1, { ReactNode } from 'react'; /** * 기본 UseQuery 옵션 (공통 속성) */ interface BaseUseQueryOptions<T = any> { cacheKey: readonly unknown[]; params?: Record<string, any>; schema?: ZodType; fetchConfig?: Omit<FetchConfig, "url" | "method" | "params" | "data">; enabled?: boolean; staleTime?: number; select?: (data: T) => any; selectDeps?: any[]; /** * placeholderData: fetch 전 임시 데이터 또는 이전 데이터 유지 * 값 또는 함수(prevData, prevQuery) 모두 지원 * ReactNode(JSX)도 허용 */ placeholderData?: T | React.ReactNode | ((prevData: T | React.ReactNode | undefined, prevQuery?: any) => T | React.ReactNode); /** * gcTime: 쿼리 데이터가 사용되지 않을 때(구독자가 0이 될 때) 가비지 컬렉션까지의 시간(ms) * 이는 생명주기 관리 전략으로, maxQueries(메모리 보호)와는 별개로 동작합니다. * @default 300000 (5분) */ gcTime?: number; } /** * URL 기반 UseQuery 옵션 */ interface UrlBasedUseQueryOptions<T = any> extends BaseUseQueryOptions<T> { /** * API 요청 URL */ url: string; /** * queryFn이 있으면 안됨 (상호 배제) */ queryFn?: never; } /** * Custom Function 기반 UseQuery 옵션 */ interface FunctionBasedUseQueryOptions<T = any> extends BaseUseQueryOptions<T> { /** * 복잡한 요청을 위한 커스텀 쿼리 함수 * Options 방식에서는 QueryFetcher만 전달 (GET/HEAD 메서드만 허용) * 인자: fetcher (QueryFetcher 인스턴스) */ queryFn: (fetcher: next_unified_query_core.QueryFetcher) => Promise<T>; /** * url이 있으면 안됨 (상호 배제) */ url?: never; } /** * UseQuery 옵션 * URL 방식 또는 Custom Function 방식 중 하나를 선택할 수 있음 */ type UseQueryOptions<T = any> = UrlBasedUseQueryOptions<T> | FunctionBasedUseQueryOptions<T>; /** * Schema에서 타입을 추출하는 도우미 타입 */ type InferSchemaType<T> = T extends { schema: infer S; } ? S extends ZodType ? next_unified_query_core.z.infer<S> : any : any; type UseQueryFactoryOptions<P, T> = Omit<UseQueryOptions<T>, "cacheKey" | "url" | "queryFn" | "params" | "schema" | "fetchConfig"> & (P extends void ? { params?: P; } : keyof P extends never ? { params?: P; } : { params: P; }); /** * 캐싱과 상태 관리를 제공하는 데이터 페칭 React 훅입니다. * * **환경 호환성:** * - ❌ 서버사이드: 서버 컴포넌트와 호환되지 않음 (React context 사용) * - ✅ 클라이언트사이드: React context가 있는 React 컴포넌트에서 사용 * - ⚠️ SSR: "use client" 지시어가 있는 클라이언트 컴포넌트에서만 사용 * * @example * ```typescript * // 클라이언트 컴포넌트에서만 사용 * "use client"; * import { useQuery } from 'next-unified-query/react'; * * function UserProfile({ userId }: { userId: number }) { * const { data, isLoading, error } = useQuery(api.getUser, { params: userId }); * * if (isLoading) return <div>Loading...</div>; * if (error) return <div>Error: {error.message}</div>; * return <div>Hello {data.name}</div>; * } * ``` */ declare function useQuery<T, E = FetchError>(query: QueryConfig<any, any>, options: UseQueryFactoryOptions<ExtractParams<typeof query>, T>): QueryObserverResult<T, E>; declare function useQuery<Q extends QueryConfig<any, any>, E = FetchError>(query: Q, options: UseQueryFactoryOptions<ExtractParams<Q>, ExtractQueryData<Q>>): QueryObserverResult<ExtractQueryData<Q>, E>; declare function useQuery<O extends UseQueryOptions<any> & { schema: ZodType; }, E = FetchError>(options: O): QueryObserverResult<InferSchemaType<O>, E>; declare function useQuery<T, E = FetchError>(options: UseQueryOptions<T>): QueryObserverResult<T, E>; /** * Mutation 상태 인터페이스 */ interface MutationState<TData = unknown, TError = FetchError<ApiErrorResponse>, TVariables = void> { data: TData | undefined; error: TError | null; isPending: boolean; isSuccess: boolean; isError: boolean; } /** * 기본 UseMutation 옵션 (공통 속성) */ interface BaseUseMutationOptions<TData = unknown, TError = FetchError<ApiErrorResponse>, TVariables = void, TContext = unknown, RequestSchema extends ZodType = ZodType, ResponseSchema extends ZodType = ZodType> { onMutate?: (variables: TVariables) => Promise<TContext | void> | TContext | void; onSuccess?: (data: InferIfZodSchema<ResponseSchema, TData>, variables: TVariables, context: TContext | undefined) => Promise<void> | void; onError?: (error: TError, variables: TVariables, context: TContext | undefined) => Promise<void> | void; onSettled?: (data: InferIfZodSchema<ResponseSchema, TData> | undefined, error: TError | null, variables: TVariables, context: TContext | undefined) => Promise<void> | void; invalidateQueries?: string[][] | ((data: InferIfZodSchema<ResponseSchema, TData>, variables: TVariables, context: TContext | undefined) => string[][]); fetchConfig?: Omit<RequestConfig, "url" | "method" | "params" | "data" | "schema">; requestSchema?: RequestSchema; responseSchema?: ResponseSchema; } /** * URL 기반 UseMutation 옵션 */ interface UrlBasedUseMutationOptions<TData = unknown, TError = FetchError<ApiErrorResponse>, TVariables = void, TContext = unknown, RequestSchema extends ZodType = ZodType, ResponseSchema extends ZodType = ZodType> extends BaseUseMutationOptions<TData, TError, TVariables, TContext, RequestSchema, ResponseSchema> { /** * API 요청 URL */ url: string | ((variables: TVariables) => string); /** * HTTP 메서드 */ method: HttpMethod; /** * mutationFn이 있으면 안됨 (상호 배제) */ mutationFn?: never; } /** * Function 기반 UseMutation 옵션 (통일된 시그니처) */ interface UnifiedMutationOptions<TData = unknown, TError = FetchError<ApiErrorResponse>, TVariables = any, TContext = unknown, RequestSchema extends ZodType = ZodType, ResponseSchema extends ZodType = ZodType> extends BaseUseMutationOptions<TData, TError, TVariables, TContext, RequestSchema, ResponseSchema> { /** * Unified mutation function - 모든 경우에 (variables, fetcher) 패턴 사용 * void mutation인 경우 variables를 _ 또는 무시하고 사용 */ mutationFn: (variables: TVariables, fetcher: NextTypeFetch) => Promise<InferIfZodSchema<ResponseSchema, TData>>; /** * url/method가 있으면 안됨 (상호 배제) */ url?: never; method?: never; } /** * UseMutation 옵션 * URL 방식 또는 Custom Function 방식 중 하나를 선택할 수 있음 */ type UseMutationOptions<TData = unknown, TError = FetchError<ApiErrorResponse>, TVariables = any, TContext = unknown, RequestSchema extends ZodType = ZodType, ResponseSchema extends ZodType = ZodType> = UrlBasedUseMutationOptions<TData, TError, TVariables, TContext, RequestSchema, ResponseSchema> | UnifiedMutationOptions<TData, TError, TVariables, TContext, RequestSchema, ResponseSchema>; /** * UseMutation 결과 인터페이스 (단순화된 시그니처) */ interface UseMutationResult<TData = unknown, TError = FetchError<ApiErrorResponse>, TVariables = any> extends MutationState<TData, TError, TVariables> { mutate: (variables: TVariables, options?: { onSuccess?: (data: TData, variables: TVariables, context: any) => void; onError?: (error: TError, variables: TVariables, context: any) => void; onSettled?: (data: TData | undefined, error: TError | null, variables: TVariables, context: any) => void; }) => void; mutateAsync: (variables?: TVariables, options?: { onSuccess?: (data: TData, variables: TVariables, context: any) => void; onError?: (error: TError, variables: TVariables, context: any) => void; onSettled?: (data: TData | undefined, error: TError | null, variables: TVariables, context: any) => void; }) => Promise<TData>; reset: () => void; } /** * useMutation 오버로드 선언 */ declare function useMutation<TVariables = any, TError = FetchError<ApiErrorResponse>, TContext = unknown, RequestSchema extends ZodType = ZodType, ResponseSchema extends ZodType = ZodType>(options: UseMutationOptions<unknown, TError, TVariables, TContext, RequestSchema, ResponseSchema> & { responseSchema: ResponseSchema; }): UseMutationResult<z.infer<ResponseSchema>, TError, TVariables>; declare function useMutation<TData = unknown, TError = FetchError<ApiErrorResponse>, TVariables = any, TContext = unknown>(factoryConfig: MutationConfig<TVariables, TData, TError, TContext>, overrideOptions?: Partial<BaseUseMutationOptions<TData, TError, TVariables, TContext>>): UseMutationResult<TData, TError, TVariables>; declare function useMutation<TData = unknown, TError = FetchError<ApiErrorResponse>, TVariables = any, TContext = unknown>(options: UseMutationOptions<TData, TError, TVariables, TContext>): UseMutationResult<TData, TError, TVariables>; declare function HydrationBoundary({ state, children, }: { state?: Record<string, QueryState>; children: ReactNode; }): React$1.JSX.Element; interface QueryClientProviderProps { /** * QueryClient 인스턴스 (선택사항) * 제공하지 않으면 자동으로 환경에 맞는 인스턴스를 생성합니다. */ client?: QueryClient; /** * QueryClient 옵션 (client가 제공되지 않은 경우에만 사용) */ options?: QueryClientOptionsWithInterceptors; children: ReactNode; } declare function QueryClientProvider({ client, options, children }: QueryClientProviderProps): React$1.JSX.Element; declare function useQueryClient(): QueryClient; export { HydrationBoundary, QueryClientProvider, useMutation, useQuery, useQueryClient };