넥스트 Next.js
12. Next.js 15에서 Form 처리 및 유효성 검사 (React Hook Form, Zod)
안녕하세요! 태마입니다.
Next.js 기초 강좌입니다.
강좌의 경우
1. 주제 간단 정리
2. 상세 주제 정리
으로 이루어져 있습니다.
넥스트 Next.js
포스팅 시작하겠습니다 :)
1. 주제 간단 정리
1. Next.js 15에서 Form 처리가 중요한 이유
웹 애플리케이션에서 Form(입력 폼)은 사용자와 상호작용하는 필수적인 요소이다.
Next.js 15에서는 React Hook Form과 Zod를 활용하여 폼 데이터를 효율적으로 관리하고 유효성 검사를 할 수 있다.
📌 Next.js 15에서 Form을 처리할 때 고려해야 할 요소
✔ 상태 관리 (useState, useReducer, React Hook Form 등)
✔ 유효성 검사 (Zod, Yup, HTML 기본 검증 등)
✔ 서버 및 API 통신 (API Routes, DB 저장, Fetch 사용)
✔ UX 개선 (에러 메시지, 필드 강조, 로딩 상태 표시 등)
✅ Form 처리 방법 비교
방식설명장점단점
useState 사용 | 기본적인 상태 관리 방식 | ✅ 간단하고 직관적 | ❌ 코드가 많아질 수 있음 |
React Hook Form 사용 | 폼 관리를 위한 라이브러리 | ✅ 최적화, 간결한 코드 | ❌ 추가 패키지 설치 필요 |
Zod를 활용한 검증 | 타입 안전한 유효성 검사 | ✅ 타입스크립트와 완벽 호환 | ❌ 초기 설정 필요 |
API Routes와 연동 | 서버로 데이터 전송 및 저장 | ✅ 백엔드 없이 가능 | ❌ API 설계 필요 |
📌 Next.js 15에서는 "React Hook Form + Zod" 조합이 가장 많이 사용됨!
2. Next.js 15에서 기본적인 Form 처리 방법
✅ 1) useState를 활용한 기본적인 Form 처리 (app/form/basic/page.tsx)
"use client";
import { useState } from "react";
export default function BasicForm() {
const [formData, setFormData] = useState({ name: "", email: "" });
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
console.log("Form Data:", formData);
};
return (
<form onSubmit={handleSubmit}>
<input name="name" value={formData.name} onChange={handleChange} placeholder="이름" />
<input name="email" value={formData.email} onChange={handleChange} placeholder="이메일" />
<button type="submit">제출</button>
</form>
);
}
📌 기본적인 useState를 사용한 폼 처리 방식 (비효율적일 수 있음).
✅ 2) React Hook Form을 활용한 Form 관리 (app/form/hookform/page.tsx)
"use client";
import { useForm } from "react-hook-form";
export default function HookForm() {
const { register, handleSubmit } = useForm();
const onSubmit = (data: any) => {
console.log("Form Data:", data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name")} placeholder="이름" />
<input {...register("email")} placeholder="이메일" />
<button type="submit">제출</button>
</form>
);
}
📌 React Hook Form을 사용하면 useState 없이도 간결한 코드 작성 가능!
✅ 3) Zod를 활용한 유효성 검사 추가 (app/form/zod/page.tsx)
📌 Zod 설치 (타입 기반 유효성 검사 라이브러리)
$ npm install zod @hookform/resolvers
📌 Zod를 활용한 Form 검증 코드
"use client";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
const schema = z.object({
name: z.string().min(2, "이름은 최소 2자 이상이어야 합니다."),
email: z.string().email("유효한 이메일을 입력하세요."),
});
export default function ZodForm() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema),
});
const onSubmit = (data: any) => {
console.log("Validated Form Data:", data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name")} placeholder="이름" />
{errors.name && <p>{errors.name.message}</p>}
<input {...register("email")} placeholder="이메일" />
{errors.email && <p>{errors.email.message}</p>}
<button type="submit">제출</button>
</form>
);
}
📌 Zod를 사용하면 강력한 유효성 검증이 가능하며, TypeScript와 완벽하게 호환된다!
✅ 여기까지 Next.js 15에서 Form 처리 및 유효성 검사 방법을 배웠습니다!
👉 "그렇다면, Next.js 15에서 Form 데이터를 API와 연결하려면?"
✅ 2부에서 Next.js 15의 API Routes와 연동하여 Form 데이터를 서버에 저장하는 방법을 배워봅시다!
2. 상세 주제 정리
1. Next.js 15에서 Form 데이터를 API Routes와 연동하기
✅ 1) Form 데이터를 서버에 저장하는 API (app/api/form/route.ts)
import prisma from "@/lib/prisma";
export async function POST(req: Request) {
const { name, email } = await req.json();
const user = await prisma.user.create({
data: { name, email },
});
return new Response(JSON.stringify(user), {
headers: { "Content-Type": "application/json" },
status: 201,
});
}
📌 Form에서 입력한 데이터를 Prisma를 활용하여 데이터베이스에 저장!
✅ 2) Form 데이터를 API로 전송 (app/form/api/page.tsx)
"use client";
import { useForm } from "react-hook-form";
export default function ApiForm() {
const { register, handleSubmit } = useForm();
const onSubmit = async (data: any) => {
const res = await fetch("/api/form", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
const result = await res.json();
console.log("서버 응답:", result);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name")} placeholder="이름" />
<input {...register("email")} placeholder="이메일" />
<button type="submit">제출</button>
</form>
);
}
📌 API Routes와 연동하여 Form 데이터를 서버로 전송 가능!
✅ 3) 서버로부터 저장된 데이터 가져오기 (app/form/list/page.tsx)
async function getUsers() {
const res = await fetch("/api/form");
return res.json();
}
export default async function UsersPage() {
const users = await getUsers();
return (
<main>
<h1>👥 등록된 사용자</h1>
<ul>
{users.map((user: any) => (
<li key={user.id}>{user.name} ({user.email})</li>
))}
</ul>
</main>
);
}
📌 서버에서 저장된 Form 데이터를 가져와서 화면에 출력 가능!
✅ 여기까지 Next.js 15에서 Form 데이터를 관리하고 API와 연동하는 방법을 배웠습니다!
👉 "그렇다면, Next.js 15에서 이미지를 최적화하려면?"
✅ 다음 회차에서 Next.js 15에서 이미지 최적화 및 Dynamic Image Processing을 배워봅시다!