useFormStatus

Odyssey·2025년 2월 7일

Next.js_study

목록 보기
28/58
post-thumbnail

2025.2.7 금요일의 공부기록

useFormStatus폼 제출(submit) 상태를 추적하는 React 훅으로,
폼 제출 중 상태(Pending), 응답 데이터(Data), HTTP 메서드(Method), Action URL을 가져올 수 있다.

이 훅을 사용하면 버튼 비활성화, 로딩 UI 표시, 성공/실패 메시지 출력 등을 쉽게 구현할 수 있다.

🔗 공식 문서:


useFormStatus 기본 사용법

📌 폼 제출 중 버튼 비활성화하기

"use client";

import { useFormStatus } from "react-dom";

function SubmitButton() {
  const { pending } = useFormStatus();

  return (
    <button type="submit" disabled={pending} className="bg-blue-500 text-white px-4 py-2 rounded-md">
      {pending ? "Submitting..." : "Submit"}
    </button>
  );
}

📌 설명:

  • useFormStatus()를 사용하여 폼이 제출 중인지 확인.
  • pending 값이 true일 때 버튼을 비활성화(disabled).
  • pendingtrue"Submitting..." 표시, false"Submit" 표시.

useFormStatus를 활용한 로그인 폼

1️⃣ 서버 액션 (server-actions.ts)

"use server";

export async function handleLogin(formData: FormData) {
  const email = formData.get("email")?.toString();
  const password = formData.get("password")?.toString();

  if (!email || !password) {
    return { success: false, message: "이메일과 비밀번호를 입력하세요." };
  }

  if (email === "test@example.com" && password === "1234") {
    return { success: true, message: "로그인 성공" };
  } else {
    return { success: false, message: "이메일 또는 비밀번호가 올바르지 않습니다." };
  }
}

📌 설명:

  • "use server"를 선언하여 이 함수가 서버에서 실행됨.
  • 폼 데이터 검증 후 성공/실패 메시지를 반환.

2️⃣ 로그인 폼 컴포넌트 (login.tsx)

"use client";

import { useState } from "react";
import { handleLogin } from "@/server-actions";
import { useFormStatus } from "react-dom";

function SubmitButton() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending} className="bg-blue-500 text-white px-4 py-2 rounded-md">
      {pending ? "Logging in..." : "Log In"}
    </button>
  );
}

export default function LogIn() {
  const [message, setMessage] = useState("");

  const handleSubmit = async (formData: FormData) => {
    const response = await handleLogin(formData);
    setMessage(response.message);
  };

  return (
    <div className="flex flex-col gap-10 py-8 px-6">
      <h1 className="text-2xl">로그인</h1>
      <form action={handleSubmit} className="flex flex-col gap-3">
        <input name="email" type="email" placeholder="Email" className="border p-2" required />
        <input name="password" type="password" placeholder="Password" className="border p-2" required />
        <SubmitButton />
      </form>
      {message && <p className="text-red-500">{message}</p>}
    </div>
  );
}

📌 설명:

  • SubmitButton 컴포넌트에서 useFormStatus()를 사용해 버튼 상태 관리.
  • 폼 제출 시 pending 상태가 true가 되어 버튼이 "Logging in..."으로 변경됨.
  • 서버 액션(handleLogin)을 호출하여 응답 메시지를 setMessage(response.message)로 표시.

useFormStatus 활용 예제 모음

1️⃣ 폼 제출 중 로딩 UI 추가

function SubmitButton() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending} className="bg-blue-500 text-white px-4 py-2 rounded-md">
      {pending ? <span className="loader"></span> : "Submit"}
    </button>
  );
}

📌 설명:

  • pending 상태일 때 로딩 애니메이션(loader CSS 클래스 적용).

2️⃣ 폼이 제출된 후 성공/실패 메시지 표시

function FormMessage() {
  const { data } = useFormStatus();
  return data ? <p className="text-green-500">{data.message}</p> : null;
}

📌 설명:

  • useFormStatus().data를 사용하여 서버 응답을 활용.

기존 방식 vs 최신 방식 (useFormStatus 활용)

기능기존 방식 (useState 사용)최신 방식 (useFormStatus 활용)
상태 관리useState()로 수동 업데이트자동으로 pending 값 관리
버튼 비활성화setLoading(true) 후 비활성화disabled={pending}으로 간단 처리
데이터 반응성상태값을 setMessage()로 수동 반영useFormStatus().data로 자동 업데이트
클린 코드useEffect + useState 조합 필요useFormStatus() 하나로 해결

📌 결론:

  • useFormStatus를 사용하면 폼 상태를 자동으로 관리할 수 있어 코드가 훨씬 간결하고 직관적이다.
  • 이제 useState로 수동으로 isLoading을 관리하지 않아도 된다! 🚀
✅ 기능🛠 설명
폼 제출 상태 확인const { pending } = useFormStatus();
폼 제출 중 버튼 비활성화<button disabled={pending}>Submit</button>
서버 응답 데이터 활용const { data } = useFormStatus();
클라이언트 상태 관리 최소화useState 없이 자동 상태 관리

📌 더 자세한 내용은 React 공식 문서를 참고하자! 🎯

0개의 댓글