본문 바로가기

개발 공부/React

React useActionState

React의 useActionState 훅은 서버 액션(Server Actions)과 함께 사용되며, 클라이언트에서 서버 액션을 실행하고 그 상태를 관리할 수 있도록 도와줍니다

useActionState

useActionState는 React에서 제공하는 훅으로, 서버 액션을 실행하고 해당 액션의 상태를 추적할 수 있도록 해줍니다.

이를 활용하면 클라이언트에서 서버 액션을 호출한 후, 그 결과를 손쉽게 상태로 관리할 수 있습니다.

주요 특징

  • 서버 액션을 클라이언트 컴포넌트에서 직접 실행 가능
  • 상태를 자동으로 관리하여 폼 처리 등에 유용
  • useStateuseReducer 없이도 서버 상태를 간편하게 핸들링

예시

'use client';

import { useActionState } from 'react';

async function createInvoice(formData: FormData) {
  const data = Object.fromEntries(formData.entries());
  const response = await fetch('/api/invoices', {
    method: 'POST',
    body: JSON.stringify(data),
    headers: { 'Content-Type': 'application/json' },
  });
  return response.json();
}

const initialState = { status: '', message: '' };

export default function InvoiceForm() {
  const [state, formAction] = useActionState(createInvoice, initialState);
  
  return (
    <form action={formAction}>
      <input name="amount" type="number" placeholder="Amount" required />
      <button type="submit">Create Invoice</button>
      {state.status && <p>{state.message}</p>}
    </form>
  );
}

 

서버 액션 함수

  • createInvoice 함수는 FormData를 받아 API 요청을 보낸 후 응답을 반환합니다.

useActionState 사용

  • useActionState(createInvoice, initialState)를 사용하여 서버 액션을 실행하고 상태를 관리합니다.
  • state는 액션의 실행 결과를 저장하며, formActionformaction 속성에 설정하여 폼 제출 시 실행되도록 합니다.

UI 렌더링

  • 사용자가 폼을 제출하면 서버 액션이 실행되고, 그 결과가 state에 저장되어 화면에 반영됩니다.

 기존 상태 관리 방식과 비교

방식특징

useState 클라이언트 측에서만 상태 관리 가능
useReducer 복잡한 상태 로직을 관리하는 데 적합
useActionState 서버 액션을 실행하고 결과를 자동으로 관리

 

 


예제

로딩 상태 추가

const [state, formAction, isPending] = useActionState(createInvoice, initialState);

return (
  <form action={formAction}>
    <input name="amount" type="number" placeholder="Amount" required />
    <button type="submit" disabled={isPending}>{isPending ? 'Processing...' : 'Create Invoice'}</button>
    {state.status && <p>{state.message}</p>}
  </form>
);

에러 핸들링 추가

async function createInvoice(formData: FormData) {
  try {
    const data = Object.fromEntries(formData.entries());
    const response = await fetch('/api/invoices', { method: 'POST', body: JSON.stringify(data), headers: { 'Content-Type': 'application/json' }, });
    if (!response.ok) throw new Error('Failed to create invoice');
    return response.json();
  } catch (error) {
    return { status: 'error', message: error.message };
  }
}

 

'개발 공부 > React' 카테고리의 다른 글

Next.js Middleware  (0) 2025.03.09
NextAuth.js의 보안 시크릿 키  (0) 2025.03.07
React Dynamic Route Segments  (0) 2025.03.03
Next.js revalidatePath, redirect  (0) 2025.02.26
React Streaming, Suspense  (0) 2025.02.25