useNexusAction
useNexusAction은 서버 액션을 감싸는 클라이언트 사이드 훅입니다. isPending, result, error와 같은 상태 관리와 생명주기 콜백을 제공하여, 클라이언트에서 트리거되는 서버 사이드 로직을 더 쉽게 다룰 수 있게 해줍니다.
Import
import { useNexusAction } from 'next-nexus/client';핵심 개념 (Core Concepts)
언제 사용하나요?
useNexusAction은 서버에서만 실행되어야 하는 로직(예: 데이터베이스 직접 접근, 서버 전용 시크릿 사용)을 클라이언트 컴포넌트에서 일반 함수처럼 호출하고 싶을 때 이상적입니다. 작업을 definition으로 모델링할 필요가 없는 경우 useNexusMutation보다 가볍게 사용할 수 있는 대안입니다.
상태 관리 (State Management)
이 훅은 서버 액션의 실행 상태를 추적하여 isPending, result, error 상태를 제공하므로, 반응형 UI를 쉽게 구축할 수 있습니다.
시그니처 (Signature)
파라미터 (Parameters)
serverAction:(...args: TArgs) => Promise<TResult>— 서버 액션 함수 자체.options?: 생명주기 콜백을 설정하는 선택적 객체.
반환 값 (Return Value)
다음을 포함하는 객체:
execute:(...args: TArgs) => void— 액션을 실행하고 결과를 기다리지 않는 함수.executeAsync:(...args: TArgs) => Promise<TResult>— 액션의 결과를await할 수 있는Promise를 반환하는 함수.isPending:booleanresult:TResult | undefinederror:Error | nullreset:() => void
Options
onStart?:(...args: TArgs) => void | Promise<void>onSuccess?:(result: TResult, ...args: TArgs) => void | Promise<void>onError?:(error: Error, ...args: TArgs) => void | Promise<void>onSettled?:(result?: TResult, error?: Error, ...args: TArgs) => void | Promise<void>
예제 (Example)
이 예제에서는 서버 액션을 사용해 상품명을 업데이트합니다. useNexusAction 훅이 버튼의 pending 상태를 관리합니다.
'use client'
import { useNexusAction } from 'next-nexus/client'
import { revalidateServerTags } from 'next-nexus'
import { revalidateClientTags } from 'next-nexus/client'
// 이 액션은 app/actions.ts와 같은 별도 파일에 있다고 가정합니다.
async function updateProductNameAction(id: string, name: string) {
'use server'
// ... 상품명을 업데이트하는 데이터베이스 로직
await revalidateServerTags(['products', `product:${id}`]);
return { success: true, newName: name };
}
export function UpdateProductName({ productId }: { productId: string }) {
const { execute, isPending } = useNexusAction(updateProductNameAction, {
onSuccess: (data) => {
revalidateClientTags(['products', `product:${productId}`]);
alert(`상품명이 ${data.newName}(으)로 변경되었습니다.`);
}
});
return (
<button onClick={() => execute(productId, '새로운 이름')} disabled={isPending}>
{isPending ? '변경 중…' : '이름 변경'}
</button>
);
}함께 보기