React/Next

[NEXT.js (ver 14)] Server action(useFormStatus, useActionState

래모 2024. 7. 10. 18:16

기존 NEXT에선 react-hook-form을 사용했었는데

현재는 서버 액션으로 쉽게 바꿀 수 있다 ! 어떻게 하는지 살펴보자

 


Server Action

사실 너무너무너무 간단하다 기존 form 태그에 action으로 함수를 전달해주면 된다

import Button from "@/components/Button";
import Input from "@/components/Input";

const Login = () => {
    const handleForm = async (formData: FormData) => {
        "use server"
        console.log(formData)
    }
    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={handleForm} className="flex flex-col gap-3">
                <Input name="email" type="email" placeholder="Email" required errors={[]} />
                <Input
                    name="password"
                    type="password"
                    placeholder="Password"
                    required
                    errors={[]}
                />
                <Button loading={false} text="Log in" />
            </form>
        </div>
    );
};

export default Login;

 

주의해야할 점은 input에 name 속성을 작성해주어야 한다.

 

함수 내부에서 "use server"을 사용해주면

POST 요청을 쉽게 할 수 있다!!

 

이후 버튼을 눌러보면 콘솔창에 이렇게 뜬다

 

onSubmit에 handleSubmit을 넣어서 하던걸 이렇게 쉽게 할 수 있다니!!

 


 

useFormStatus

: 마지막 양식 제출의 status 정보를 제공하는 Hook

 

const { pending, data, method, action } = useFormStatus();

 

form의 자식에만 적용 가능

자동으로 상위의 form 태그를 추적해 정보를 찾는다

 

1) pending

  • 제출중이면 true
  • 아니면 false

2) data

  • form이 제출하는 데이터를 포함하는 FormData 인터페이스를 구현한 객체
  • 활성화된 제출이 없거나 <form> 부모가 없으면 null이 된다.

3) method

  • get 또는 post (string)
  • HTTP 메소드 중 어떤 것으로 제출되는지 알려준다.
  • (기본적으로 <form>은 GET 메소드를 사용하고, method 속성을 통해 지정할 수 있다.)

4) action

  • 부모 <form>의 action 속성에 전달된 함수에 대한 참조
  • action 속성에 URI값이 제공되었거나 지정되지 않았으면 null이 된다.

 

useActionState

: 폼 액션의 결과를 기반으로 state를 업데이트할 수 있도록 제공하는 Hook

const [state, formAction] = useActionState(fn, initialState, permalink?);

 

폼 state는 폼을 마지막으로 제출했을 때 액션에서 반환되는 값!

폼이 제출되기 전이라면 전달한 초기 state와 같음

Server Action과 함께 사용하는 경우, useActionState를 사용하여 hydration이 완료되기 전에도 폼 제출에 대한 서버의 응답을 보여줄 수 있음

import { useActionState } from 'react';
import { action } from './actions.js';

function MyComponent() {
  const [state, formAction] = useActionState(action, null);
  // ...
  return (
    <form action={formAction}>
      {/* ... */}
    </form>
  );
}

 

리액트 18.3.1 버전 이상부터 사용 가능

 

그 전 버전은 useFormState를 사용한다