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를 사용한다