Next.js 15에서 useActionState를 통해 서버 액션 쉽게 사용하기
2024-11-17 05:43:49Next.js 15에서 useActionState로 서버 액션 관리하기
Next.js 15가 출시되면서 많은 개발자들이 주목하고 있는 기능 중 하나가 바로 useActionState입니다. 이 훅은 폼 데이터를 서버 액션으로 전달하고 처리하기 위한 새롭고 강력한 방법을 제공합니다. 특히 서버에서 폼 데이터를 받아오는 과정에서 상태 관리가 필요할 때 유용합니다. 본 글에서는 useActionState를 활용하여 서버 액션을 이해하고, 예제를 통해 그 활용법을 빠르게 익혀보겠습니다.
useActionState 소개
useActionState는 폼의 값을 쉽게 서버 액션에 전달하도록 설계되었습니다. 또한 서버 액션의 반환값을 자동으로 상태 변수에 업데이트하는 기능도 갖추고 있어, 폼 입력 필드의 유효성 검사 오류를 편리하게 랜더링할 수 있습니다.
먼저, 이 훅을 이해하기 위해 가장 기본적인 형태의 예제를 살펴보겠습니다.
SignUp 컴포넌트 예제
"use client";
import { useActionState } from "react";
import { signUp } from "../actions";
export default function SignUp() {
const [state, action] = useActionState(signUp, {});
return (
<form action={action}>
<div>
<label htmlFor="username">Username:</label>
<input
type="text"
id="username"
name="username"
defaultValue={state.username}
required
/>
{state.errors?.username && (
<p className="text-sm text-red-500">{state.errors.username}</p>
)}
</div>
<div>
<label htmlFor="password">Password:</label>
<input
type="password"
id="password"
name="password"
defaultValue={state.password}
/>
{state.errors?.password && (
<p className="text-sm text-red-500">{state.errors.password}</p>
)}
</div>
<input type="submit" value="Sign Up" />
</form>
);
}
위 코드에서 보듯이 useActionState는 폼의 action과 state를 동시에 관리합니다. state는 서버의 응답에 따라 자동으로 업데이트되며, 이로 인해 폼 필드의 상태를 쉽게 검사할 수 있습니다.
actions.ts에서의 검사 및 처리
useActionState와 함께 서버 측에서는 아래와 같은 방식으로 데이터를 처리합니다. 데이터 검증을 위해 zod 라이브러리를 사용했습니다.
"use server";
import { z } from "zod";
const SignUpSchema = z.object({
username: z.string(),
password: z
.string()
.min(8, { message: "Be at least 8 characters long" })
.regex(/[a-zA-Z]/, { message: "Contain at least one letter." })
.regex(/[0-9]/, { message: "Contain at least one number." })
.regex(/[^a-zA-Z0-9]/, {
message: "Contain at least one special character.",
})
.trim(),
});
export type SignUpActionState = {
username?: string;
password?: string;
errors?: {
username?: string[];
password?: string[];
};
};
export async function signUp(
_prevState: SignUpActionState,
form: FormData
): Promise<SignUpActionState> {
const username = form.get("username") as string;
const password = form.get("password") as string;
const validatedFields = SignUpSchema.safeParse({
username,
password,
});
if (!validatedFields.success) {
return {
username,
password,
errors: validatedFields.error.flatten().fieldErrors,
};
}
// process validated form inputs here
return { username, password };
}
이와 같은 서버의 검증 과정은 클라이언트 측에서 들어오는 데이터를 엄격히 관리할 수 있도록 도와줍니다. 데이터를 수집하여 zod 스키마로 검증하고, 유효한 경우 추가적인 처리를 할 수 있습니다.
isPending 속성 활용하기
useActionState는 또 다른 유용한 속성을 제공합니다. 바로 isPending입니다. 이 속성은 서버 액션의 프라미스가 아직 해결되지 않았음을 나타내며, 사용자가 폼 제출을 여러 번 누르지 못하도록 폼 요소를 일시적으로 비활성화하는 데 사용될 수 있습니다.
useActionState의 이점
이 훅은 useFormAction과 useFormStatus의 기능을 합친 것과 유사하며, 이젠 서버 액션을 폼뿐만 아니라 버튼과 다른 요소에서도 사용할 수 있어 명확히 개선된 점이 보입니다. 특히 Next.js 15에서는 useFormStatus가 더 이상 사용되지 않으므로 새로운 useActionState를 사용해야 합니다.
여러 가지 면에서 useActionState는 UX를 향상시키고 개발자의 작업을 간소화합니다. 입력 필드의 관리, 서버와의 상호작용, 그리고 데이터 유효성 검사를 쉽게 처리할 수 있으므로 확장성이 뛰어난 애플리케이션을 개발할 수 있습니다.
결론
Next.js 15의 useActionState는 서버 액션을 효율적으로 관리할 수 있는 강력한 툴입니다. 이 글을 통해 기본적인 사용법과 이점을 이해하고, 실제 프로젝트에 적용하여 서버와의 상호작용을 더욱 수월하게 만드세요.