사용하는 사람이 많아서 막혔을 때 검색하면 답을 찾기 쉽습니다. shadcn/ui의 폼도 이 조합입니다
결과 비교
같은 것을 각 라이브러리로 만들었습니다. 직접 만져 보세요.
React Hook Form + Zod
TanStack Form
코드 비교
코드를 고치면 오른쪽 미리보기가 바로 바뀝니다.
내 프로젝트에서 이 예제를 실행하려면:npx shadcn@latest add button input label
import{useForm}from"react-hook-form"import{zodResolver}from"@hookform/resolvers/zod"import{z}from"zod"import{Button}from"./components/ui/button"import{Input}from"./components/ui/input"import{Label}from"./components/ui/label"// ① 규칙: 입력 검증 규칙을 한곳에 모아서 작성constschema = z.object({email:z.email("올바른 이메일 주소를 입력해 주세요"),password:z.string().min(8,"8자 이상 입력해 주세요").regex(/[0-9]/,"숫자를 포함해 주세요"),})// 규칙으로부터 폼 값의 타입을 만듦type FormValues = z.infer<typeofschema>
exportdefaultfunctionApp(){// 폼을 준비 (규칙은 zodResolver로 전달)const{register,handleSubmit,formState:{errors},} = useForm<FormValues>({resolver:zodResolver(schema)})// 모든 규칙을 통과했을 때만 호출됨constonSubmit = (values: FormValues)=>{alert("로그인: " + values.email)}return(<formonSubmit={handleSubmit(onSubmit)}className="flex flex-col gap-4 p-5"><divclassName="flex flex-col gap-2"><LabelhtmlFor="email">이메일</Label>{/* ② 연결: 입력란을 폼에 연결 */}
<Inputid="email"{...register("email")}/>{/* ③ 알림: 규칙에 맞지 않으면 오류를 표시 */}
{errors.email && (<pclassName="text-sm text-destructive">{errors.email.message}</p>)}</div><divclassName="flex flex-col gap-2"><LabelhtmlFor="password">비밀번호</Label><Inputid="password"type="password"{...register("password")}/>{errors.password && (<pclassName="text-sm text-destructive">{errors.password.message}</p>)}</div><Buttontype="submit">로그인</Button></form>)}