본문 바로가기

Frontend/NextJS

Next.js에서 useFormState를 활용한 폼 상태 관리

Next.js 13 이후부터 본격적으로 도입된 App Router와 함께, 서버 액션(Server Actions)을 사용하는 방식이 점점 익숙해지고 있습니다. 그 과정에서 자주 마주치게 되는 훅이 하나 있는데요, 바로 useFormState입니다.

이번 글에서는 useFormState가 어떤 역할을 하는지, 그리고 어떻게 사용하면 좋을지 정리해보려고 합니다.

기존 방식 vs 서버 액션 기반 폼 처리

기존 React 방식에서 폼 처리는 주로 클라이언트에서 useState를 써서 입력 값을 관리하고,

onSubmit에서 API 요청을 보내는 방식이 일반적이었습니다.

 

하지만 서버 액션을 쓰게 되면 폼의 전송과 처리를 서버 측에서 바로 할 수 있기 때문에 구조 자체가 달라집니다.

여기서 useFormState폼 전송 이후의 상태(예: 에러 메시지, 성공 메시지 등)를 관리하기 위한 훅입니다.

기본 사용법

간단한 예제를 보면서 흐름을 이해해봅시다.

// app/contact/page.tsx

'use client';

import { useFormState } from 'react-dom';
import { submitContactForm } from './actions';

const initialState = {
  message: '',
};

export default function ContactPage() {
  const [state, formAction] = useFormState(submitContactForm, initialState);

  return (
    <form action={formAction}>
      <label>
        이메일:
        <input name="email" type="email" required />
      </label>
      <label>
        내용:
        <textarea name="message" required />
      </label>
      <button type="submit">보내기</button>

      {state.message && <p>{state.message}</p>}
    </form>
  );
}

여기서 핵심은 useFormState(submitContactForm, initialState) 이 부분입니다.

  • submitContactForm은 서버에서 실행되는 액션 함수입니다.
  • initialState는 상태 초기값입니다.
  • formAction은 <form action={formAction}>에 넣어주면 됩니다.

서버 액션 작성 예시

// app/contact/actions.ts

'use server';

export async function submitContactForm(prevState: any, formData: FormData) {
  const email = formData.get('email')?.toString();
  const message = formData.get('message')?.toString();

  if (!email || !message) {
    return { message: '모든 항목을 입력해주세요.' };
  }

  // 실제 이메일 전송 로직이 들어갈 수 있음
  console.log('이메일 전송:', email, message);

  return { message: '문의가 성공적으로 전송되었습니다.' };
}

submitContactForm 함수는 useFormState를 통해 이전 상태(prevState)와 함께 호출됩니다.

이 덕분에 폼 제출 후 사용자에게 결과 메시지를 쉽게 보여줄 수 있습니다.

 

주의: prevState를 사용하지 않더라도 formData 인자는 예시코드처럼 꼭 두 번째 인자로 넣어줘야함.

참고로 any와 FormData는 ts 타입정의한 것임

장점 

  • 클라이언트에서 굳이 상태 관리를 따로 하지 않아도 됨
  • 서버 액션과의 연동이 자연스러움
  • 로직이 깔끔하게 분리됨

주의할 점

  • useFormState는 클라이언트 컴포넌트에서만 사용할 수 있습니다.
  • action 함수는 반드시 'use server' 지시어를 포함한 서버 함수여야 합니다.
  • 서버 액션을 사용하려면 Next.js에서 App Router를 써야 합니다 (pages 디렉토리에선 안 됨)

Next.js의 서버 액션 + useFormState 조합은 한번 익숙해지면 깔끔하고 유지보수하기 좋은 구조를 만들 수 있음

(특히 폼 검증 결과나 메시지를 쉽게 처리하고 싶을 때 유용)

'Frontend > NextJS' 카테고리의 다른 글

[NextJS 15] 이미지 최적화  (1) 2025.04.16