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 |
---|