기록

Next.js에서의 useFormStatus, useFormState

als982001 2024. 9. 29. 17:22

1. useFormStatus

  • 폼 제출을 처리하는 동안의 로딩 상태를 추적하는데 사용
  • 폼을 서버로 제출할 때 로딩 중인지를 확인하고 이를 기반으로 폼을 비활성화하거나 로딩 메시지를 표시하는데 유용
  • form의 자식 요소에서 사용해야 함
  • 반환값 중 pending으로 로딩 상태를 확인할 수 있음.

useFormStatus의 반환값

 

  • 예시 코드
"use client";

import { useFormStatus } from "react-dom";

interface ButtonProps {
  text: string;
}

export default function FormButton({ text }: ButtonProps) {
  // useFormStatus hook은 form의 자식 요소에서 사용해야 한다.
  const { pending } = useFormStatus();

  return (
    <button
      disabled={pending}
      className="primary-btn h-10 disabled:bg-neutral-400 disabled:text-neutral-300 disabled:cursor-not-allowed"
    >
      {pending ? "로딩 중" : text}
    </button>
  );
}

 

 

 

2. useFormState

  • 서버 액션(server actions)과 함께 폼의 전체 상태를 관리하는 훅
  • 서버 액션을 호출하는 함수(action)와 더불어 에러 상태, 결과 데이터 등을 반환
  • 결과를 알고 싶은 action초기 state를 인자로 넘겨주어야 함
  • 반환값 (아래 예시 코드의 배열)
    • state: 폼 제출 중 발생한 상태를 담고 있는 객체
    • dispatch: action의 트리거
  • 예시 코드
"use client";

import Input from "@/components/Input";
import Button from "@/components/Button";
import SocialLogin from "@/components/SocialLogin";
import { useFormState } from "react-dom";
import { login } from "./action";

export default function Login() {
  // useFormState는 결과를 알고 싶은 action을 인자로 넘겨줘야 함
  // action의 결과, action의 트리거(dispatch)를 돌려줌
  const [state, dispatch] = useFormState(login, null);

  console.log({ state, dispatch });

  return (
    <div className="flex flex-col gap-10 py-8 px-6">
      <div className="flex flex-col gap-2 *:font-medium">
        <h1 className="text-2xl">안녕하세요!</h1>
        <h2 className="text-xl">Log in with email and password</h2>
      </div>
      <form action={dispatch} className="flex flex-col gap-3">
        <Input
          name="email"
          type="email"
          placeholder="Email"
          required
          errors={state?.fieldErrors.email}
        />
        <Input
          name="password"
          type="password"
          placeholder="Password"
          required
          errors={state?.fieldErrors.password}
        />
        <Button text="Log in" />
      </form>
      <SocialLogin />
    </div>
  );
}

 

 

 

3. 요약

  • useFormStatus: 폼 제출 중의 로딩 상태를 추적하는데 용이하며 이를 활용해 버튼 비활성화나 로딩 상태를 표시하는데 적합
  • useFormState: 폼 제출을 처리하는 서버 액션과 관련된 전체 상태를 관리. 폼 제출 중 발생하는 에러, 결과 데이터 등을 관리하고 서버 액션을 트리거할 수 있음