useNexusMutation
useNexusMutation
은 ‘쓰기’ 작업(예: POST, PUT, DELETE)을 수행하기 위한 클라이언트 사이드 훅입니다. 요청의 진행 상태와 결과를 관리하며, 재검증이나 알림 표시 같은 부가 효과를 위한 생명주기 콜백을 제공합니다.
Import
import { useNexusMutation } from "next-nexus/client";
핵심 개념 (Core Concepts)
동작 방식
useNexusMutation
은 변수를 받아 POST, PUT, PATCH, DELETE 요청을 위한 definition
을 반환하는 팩토리 함수를 인자로 받습니다. 이 훅은 요청을 실행하는 데 사용할 수 있는 mutate
함수를 반환합니다.
동시 실행 방지 (Concurrency Guard)
이 훅은 여러 뮤테이션이 동시에 실행되는 것을 방지합니다. 요청이 이미 진행 중일 때 mutate
또는 mutateAsync
가 다시 호출되면 오류가 발생합니다. 이를 방지하려면 항상 isPending
상태를 확인하여 UI 요소를 비활성화해야 합니다.
생명주기 콜백 (Lifecycle Callbacks)
options
객체는 뮤테이션 생명주기의 여러 단계에서 부가 효과를 실행할 수 있는 콜백 함수들(onStart
, onSuccess
, onError
, onSettled
)을 지원합니다. 이 콜백들은 클라이언트 사이드 캐시 재검증이나 낙관적 업데이트 같은 액션을 수행하기에 가장 이상적인 위치입니다.
시그니처 (Signature)
파라미터 (Parameters)
factory
:(variables: TVariables) => NexusDefinition<TData>
— 뮤테이션 변수를 받아definition
을 반환하는 함수.options?
: 훅의 동작을 설정하는 선택적 객체. 아래 Options를 참고하세요.
반환 값 (Return Value)
다음을 포함하는 객체:
data
:TData | undefined
(마지막으로 성공한 뮤테이션의 데이터)headers
:Headers | undefined
error
:TError | null
isPending
,isSuccess
,isError
:boolean
mutate
:(variables: TVariables) => void
(실행 후 결과는 기다리지 않음)mutateAsync
:(variables: TVariables) => Promise<TData>
reset
:() => void
(훅의 상태를 초기화)
Options
route?
:string
- 요청을 Next.js 라우트 핸들러로 프록시합니다.onStart?
:(variables: TVariables) => TContext | Promise<TContext>
- 뮤테이션이 시작되기 전에 실행됩니다. 다른 콜백으로 전달될 컨텍스트 값을 반환할 수 있습니다.onSuccess?
:(data: TData, variables: TVariables, context?: TContext) => void | Promise<void>
- 성공 시 실행됩니다.onError?
:(error: TError, variables: TVariables, context?: TContext) => void | Promise<void>
- 오류 발생 시 실행됩니다.onSettled?
:(data?: TData, error?: TError, variables: TVariables, context?: TContext) => void | Promise<void>
- 뮤테이션이 성공 또는 실패한 후 항상 실행됩니다.
예제 (Examples)
기본 Mutation
mutate
함수에 변수를 전달하여 뮤테이션을 실행합니다. onSuccess
콜백을 사용해 클라이언트 캐시를 재검증합니다.
"use client";
import { useNexusMutation, revalidateClientTags } from "next-nexus/client";
import { productDefinition } from "@/api/productDefinition";
export function LikeButton({ id }: { id: string }) {
const { mutate, isPending } = useNexusMutation(productDefinition.like, {
onSuccess: () => {
// 이 태그를 사용하는 모든 쿼리를 무효화하고 다시 가져옵니다.
revalidateClientTags(["products"]);
},
});
return (
<button onClick={() => mutate(id)} disabled={isPending}>
{isPending ? "처리 중…" : "좋아요"}
</button>
);
}
route
프록시 사용하기
클라이언트에서 외부 API를 직접 호출하는 대신, 내부 API 라우트를 통해 요청을 프록시합니다.
"use client";
import { useNexusMutation } from "next-nexus/client";
import { productDefinition } from "@/api/productDefinition";
export function SaveButton({ id, name }: { id: string; name: string }) {
const { mutate, isPending } = useNexusMutation(productDefinition.update, {
route: "/api/internal/save",
});
return (
<button onClick={() => mutate({ id, name })} disabled={isPending}>
저장
</button>
);
}
함께 보기
- Revalidation
- nexusCache (낙관적 업데이트 구현 시)
Last updated on