카테고리 없음

useForm 정리 - 폼 형식의 상태관리

minnote29 2025. 2. 11. 00:22
전역 상태관리를 하면, 모든 코드가 전역 상태에 접근할 수 있지만, 전역 상태로 관리됨으로써 불필요한 메모리를 사용하게 되고, 의도치 않은 상태 변경이 발생하게 되면 디버깅이 매우 어려워진다. -> 한마디로, 이미 여러 데이터가 담겨있는 상태를 불러왔는데 다시 새로고침을 하면 전부 그 데이터를 다시 불러와야 한다는 것이다. 
그렇기 때문에 zustand와 react-query를 써서 상태관리를 하기 위해 store를 통해 전역 상태관리를 하려던 것을 useForm으로 유효성 검사를 하고, useController, zod, schema를 이용해서 컴포넌트 별로 상태관리를 하려는 생각을 하게 됐고, 이 글을 작성하는 계기가 됐다.

 

 

폼 형식을 간단하게 말하면 데이터들의 모음이라고 할 수 있음 -> 그렇기에 useState를 이용해서 그 많은 데이터를 관리하기에는 힘들다. -> useForm을 쓰면 된다. 

useForm

 📌 Rules (규칙)

  • undefined를 기본값(default value)으로 제공하는 것을 피해야 한다.
    → 이는 제어된 컴포넌트(controlled component)의 기본 상태와 충돌하기 때문이다.
  • defaultValues는 캐시된다.
    → 이를 초기화하려면 reset API를 사용해야 한다.
  • defaultValues는 기본적으로 제출 결과(submission result)에 포함된다.
  • Moment 또는 Luxon과 같은 프로토타입 메서드를 포함하는 커스텀 객체를 사용하지 않는 것이 좋다.
    → (defaultValues로 설정할 때 문제를 일으킬 수 있음.)
  • 폼 데이터를 포함하는 다른 옵션들도 있다.

 

 

 

useForm: UseFormProps

useForm is a custom hook for managing forms with ease.

ooptional argument

mode(보내기 전), reValidateMode(보낸 후), defaultValues(폼의 디폴트 값), values(반환값), resetOptions(새로 할당될 동안, 상태 초기화하는 옵션), criteriaMode(모든 에러 보여줌-유효성 검사), shouldFocusError(내장된 포커스 관리를 사용 or 사용하지 않도록 설정), delatError(오류 지연), shouldUseNavtiveValidation(브라우저 기본 제공 양식 제약 조건 API를 사용), shouldUnregister(언마운트하고, input unregister를 활성화 및 비활성화. ex. 언마운트 후에도 입력값을 유지함. ) register, unregister,

resolver(선호하는 schema validation 라이브러리와 통합됨.)

context(스키마 유효성 검사를 위해 제공할 컨텍스트 개체.) => 공식문서를 보면 대충 이정도의 Generic props가 있다.

 

reValidateMode: onChange | onBlur | onSubmit = 'onChange'

입력값의 유효성 검사(validation)를 언제 다시 실행할지를 결정하는 옵션. 기본값은 'onChange'이며, 사용자가 입력을 변경할 때마다 유효성 검사가 실행됨.

onSubmit string 유효성 검사는 폼이 제출될 때만 실행됨.
입력 필드는 이벤트 리스너를 연결하여 필요 시 다시 검증됨.
사용자가 submit 버튼을 눌렀을 때만 유효성 검사가 실행됨.
onBlur string 유효성 검사는 입력 필드가 포커스를 잃을 때(blur 이벤트) 실행됨.
사용자가 입력을 끝내고 다른 곳을 클릭(blur)할 때 유효성 검사가 실행됨.
onChange string 유효성 검사는 입력값이 변경될 때마다(change 이벤트) 실행됨.
⚠️ 성능에 영향을 줄 수 있음.
사용자가 입력값을 변경할 때마다(change 이벤트) 유효성 검사가 실행됨.
onTouched string 유효성 검사는 처음 한 번은 blur 이벤트에서 실행되고,
이후에는 change 이벤트에서 실행됨.
첫 번째 유효성 검사는 blur에서 실행되고, 이후에는 change에서 실행됨.
all string 유효성 검사는 blur와 change 이벤트에서 모두 실행됨.
입력 필드가 blur될 때와 change될 때 모두 유효성 검사가 실행됨.

 

defaultValues

defaultValues는 폼(form)의 초기값을 설정하는 옵션이다.
useForm()에서 입력 필드가 처음 렌더링될 때 사용할 기본값을 지정하는 역할을 한다.
즉, 폼이 처음 로드될 때 어떤 값이 기본값으로 들어갈지 결정함.

 

Props 추가 설명

values object 폼의 모든 입력값을 포함하는 객체
context object useForm 설정에 제공할 수 있는 객체 (렌더링마다 변경 가능)
options { criteriaMode: string, fields: object, names: string[] } 검증할 필드 정보와 criteriaMode 옵션을 포함하는 객체
criteriaMode `firstError all`
shouldFocusError boolean (default: true) 유효성 검사에서 에러가 발생한 필드로 자동 포커스 이동 여부
delayError number 오류 메시지 표시 지연 시간 (ms 단위)
shouldUnregister boolean (default: false) true이면 언마운트된 필드가 useForm에서 제거됨
shouldUseNativeValidation boolean (default: false) HTML의 기본 브라우저 검증을 사용할지 여부
resolver Resolver 외부 검증 라이브러리(Yup, Zod 등)를 사용하는 경우, 이를 처리하는 함수

 

 

  📌 Rules 

  1. 스키마 기반 검증(Schema validation)은 개별 필드 수준에서만 오류를 보고한다.
     부모 요소(예: 체크박스 그룹)에 대한 오류 확인은 제한적이며, 직접 부모 요소에 대한 검증을 처리해야 한다.
  2. 이 함수(resolver)는 캐시된다.
     즉, 동일한 입력값이 다시 검증될 때마다 매번 새로운 검증을 실행하지 않음.
  3. 입력값의 재검증(Re-validation)은 사용자 상호작용 중 한 번에 한 개의 필드에서만 실행된다.
     검증 오류가 있는 입력 필드가 있을 때, 전체 폼이 아니라 개별 입력값만 검증됨.
  4. resolver는 내장된 유효성 검사 기능(예: required, min 등)과 함께 사용할 수 없다.
     즉, resolver를 사용할 때는 모든 검증을 외부 라이브러리(Yup, Zod 등)를 통해 처리해야 함.
  5. 커스텀 resolver를 만들 때, 반드시 values와 errors 두 개의 속성을 반환해야 한다.
    → 기본 값은 { values: {}, errors: {} }와 같이 빈 객체로 설정해야 한다.
  6. errors 객체의 키(key)는 입력 필드의 name 속성과 동일해야 한다.
     예를 들어, name="email"인 필드는 errors.email에서 검증 결과를 가져와야 한다.

 

 

 

useController 

useController는 React Hook Form에서 Controller를 내부적으로 지원하는 커스텀 훅이다.
외부 UI 라이브러리(MUI, AntD, Chakra UI 등)와 함께 사용할 때 유용하며, 동일한 props와 methods를 제공한다.

 📌 Rules 

  1. 스키마 기반 검증(Schema validation)은 개별 필드 수준에서만 오류를 보고한다.
    → 즉, 부모 요소(예: 체크박스 그룹)에 대한 오류는 직접 처리해야 한다.
  2. 이 함수(resolver)는 캐시된다.
    → 동일한 입력값이 다시 검증될 때마다 매번 새로운 검증을 실행하지 않음.
  3. 입력값의 재검증(Re-validation)은 사용자 상호작용 중 한 번에 한 개의 필드에서만 실행된다.
    → 폼 전체가 아닌, 각 필드별로 따로 유효성 검사를 실행함.
  4. resolver는 내장된 유효성 검사 기능(예: required, min, max 등)과 함께 사용할 수 없다.
    → resolver를 사용할 경우, 모든 유효성 검사를 외부 라이브러리(Yup, Zod 등)를 통해 처리해야 한다.
  5. 커스텀 resolver를 만들 때, 반드시 values와 errors 두 개의 속성을 반환해야 한다.
    → 기본 값은 { values: {}, errors: {} }처럼 빈 객체여야 함.
  6. errors 객체의 키(key)는 입력 필드의 name 속성과 동일해야 한다.
    → 예를 들어, name="email"인 필드는 errors.email에서 검증 결과를 가져와야 한다.

 

Props 설명 (required - ✅, ❌ )

name FieldPath 폼 입력 필드의 고유한 이름. useForm의 상태에서 필드를 관리하는 데 사용됨.
control Control useForm()에서 제공하는 control 객체. FormProvider를 사용할 경우 생략 가능.
defaultValue unknown 입력 필드의 초기값. undefined는 사용할 수 없음.
rules Object 유효성 검증 규칙. required, min, max, minLength, maxLength, pattern, validate 등을 포함함.
shouldUnregister boolean = false true이면 입력 필드가 언마운트될 때 폼 상태에서도 제거됨. useFieldArray와 함께 사용할 경우 주의가 필요함.

 

 

Return 값 설명 (type - (value: any) => void, () => void, unknown, string, ref, boolean, object)

🔹 field (사용자의 입력을 관리하는 객체)

onChange (value: any) => void 사용자의 입력값을 React Hook Form으로 전달하는 함수. input의 onChange 속성에 할당해야 함.
onBlur () => void 입력 필드가 포커스를 잃을 때(blur) React Hook Form에 이벤트를 전달하는 함수.
value unknown 현재 입력 필드의 값.
name string 현재 입력 필드의 name 속성 값.
ref React.Ref 입력 필드를 React Hook Form과 연결하는 참조값. 오류 발생 시 자동 포커스를 위해 사용됨.

 

🔹 fieldState (개별 입력 필드의 상태)

invalid boolean 현재 입력 필드가 유효하지 않은 경우 true
isTouched boolean 입력 필드가 한 번이라도 포커스를 받았다가 벗어났는지 여부
isDirty boolean 입력 필드 값이 처음 값에서 변경되었는지 여부
error object 현재 필드에 대한 유효성 검증 오류 정보

 

🔹 formState (폼 전체의 상태) (type - boolean, object)

isDirty boolean 폼 내의 입력값이 처음 값에서 변경되었는지 여부 (true이면 하나 이상의 입력값이 변경됨)
dirtyFields object 사용자가 변경한 입력 필드 목록
touchedFields object 사용자가 한 번이라도 포커스를 줬던 필드 목록
defaultValues object 초기값(defaultValues)을 설정했을 경우, 그 값이 저장됨
isSubmitted boolean 폼이 제출되었는지 여부 (true이면 폼이 제출된 상태)
isSubmitSuccessful boolean 폼이 오류 없이 정상적으로 제출되었는지 여부
isSubmitting boolean 폼이 제출 중인지 여부 (true이면 제출 중)
isLoading boolean 비동기 초기값(async defaultValues)을 로드 중인지 여부 (true이면 로딩 중)
submitCount number 폼이 제출된 횟수
isValid boolean 폼 전체에 오류가 없으면 true, 오류가 있으면 false
isValidating boolean 폼이 유효성 검사 중인지 여부 (true이면 검사 중)
errors object 각 입력 필드의 유효성 검사 오류 정보