React 19 Beta의 useActionState로 폼 상태 관리 개선하기

배경

사내 어드민 페이지의 폼 처리 로직이 복잡해지면서 loading, error, success 상태를 각각 useState로 관리하고 있었다. React 19 Beta가 공개되면서 useActionState라는 훅이 추가됐는데, 폼 상태 관리에 특화된 API라고 해서 테스트해봤다.

기존 코드의 문제

const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [data, setData] = useState(null);

const handleSubmit = async (e: FormEvent) => {
  e.preventDefault();
  setLoading(true);
  setError(null);
  try {
    const result = await updateUser(formData);
    setData(result);
  } catch (err) {
    setError(err.message);
  } finally {
    setLoading(false);
  }
};

상태 관리 보일러플레이트가 많고, 에러 처리와 로딩 상태를 매번 수동으로 관리해야 했다.

useActionState 적용

const [state, submitAction, isPending] = useActionState(
  async (prevState, formData) => {
    try {
      const result = await updateUser(formData);
      return { success: true, data: result };
    } catch (error) {
      return { success: false, error: error.message };
    }
  },
  { success: false, data: null, error: null }
);

return (
  <form action={submitAction}>
    {/* form fields */}
    <button disabled={isPending}>
      {isPending ? '처리중...' : '저장'}
    </button>
    {state.error && <div>{state.error}</div>}
  </form>
);

개선된 점

  1. 상태 통합: 여러 useState를 하나의 state 객체로 관리
  2. 자동 pending 처리: isPending을 자동으로 제공
  3. Progressive Enhancement: action 속성 사용으로 JS 없이도 동작 가능
  4. 이전 상태 접근: prevState로 optimistic update 구현 가능

주의사항

아직 Beta 단계라 프로덕션 적용은 신중해야 한다. Next.js 15와 함께 사용하면 서버 액션과의 통합이 더 매끄럽지만, 현재는 클라이언트 액션 위주로만 테스트했다. 정식 릴리즈 전까지는 별도 브랜치에서 실험하는 것을 권장한다.