← 전체 글로 돌아가기

웹 개발

폼 검증 규칙이 늘어날 때 실수 줄이는 법

검증 규칙이 컴포넌트 곳곳에 흩어지면 빠뜨리기 쉽다. 한곳에 모아두는 방식으로 바꾼 경험을 적었다.

폼 필드가 두세 개일 때는 onChange에서 직접 검증해도 별 문제가 없었다. 그런데 필드가 열 개를 넘기고, 필드끼리 의존하는 규칙(비밀번호 확인, 시작일/종료일 같은 것)이 생기면서부터 검증 코드가 컴포넌트 곳곳에 흩어졌다. 어떤 규칙은 onChange에, 어떤 규칙은 onSubmit에 있고, 같은 규칙이 두 군데 중복되기도 했다.

검증을 한곳으로 모은다

가장 먼저 한 일은 검증 규칙을 컴포넌트 밖의 스키마로 빼는 것이었다. 나는 zod를 쓴다.

const schema = z.object({
  email: z.string().email("이메일 형식이 아니다"),
  password: z.string().min(8, "8자 이상"),
  passwordConfirm: z.string(),
}).refine((d) => d.password === d.passwordConfirm, {
  message: "비밀번호가 일치하지 않는다",
  path: ["passwordConfirm"],
});

이렇게 빼두면 필드 간 의존 규칙(refine)도 한곳에서 보인다. 어떤 규칙이 있는지 파악하려고 컴포넌트를 뒤질 필요가 없다.

제출 시점에 한 번에 검증한다

입력할 때마다 빨간 에러를 띄우면 사용자가 피곤하다. 나는 제출 시점에 전체를 검증하고, 한 번 에러가 난 필드만 onChange로 다시 검증하는 방식으로 맞췄다. react-hook-form의 mode: "onTouched"가 이 동작에 가깝다.

빠뜨린 규칙을 찾는 법

규칙이 스키마 한곳에 있으니, 누락은 보통 "스키마에는 있는데 화면에 에러 메시지를 안 그린" 경우다. 각 필드의 에러를 렌더링하는 부분을 스키마 키와 1:1로 맞춰두면 빠진 게 눈에 띈다. 규칙을 흩어두지 않은 것만으로 실수가 확 줄었다.