YesCoding

Go to English
search:

[React] react-hook-form 으둜 input validation ν•˜κΈ°

thumbnail react hook form

react-hook-form 을 μ‚¬μš©ν•΄μ„œ μž…λ ₯값듀이 μ œλŒ€λ‘œ μž…λ ₯λ˜μ§€ μ•Šμ€ 경우 error 처리λ₯Ό μ–΄λ–»κ²Œ μ‰½κ²Œ ν•  수 μžˆλŠ” 지 κ²½ν—˜ν•œ λ‚΄μš©μ„ κ³΅μœ ν•©λ‹ˆλ‹€.

νšŒμ›κ°€μž…μ΄λ‚˜ μœ μ € μ„ΈνŒ… νŽ˜μ΄μ§€ λ“± 정보듀을 μž…λ ₯ν•΄μ„œ μ„œλ²„μ— μ œμΆœν•˜λŠ” νŽ˜μ΄μ§€λ“€μ—μ„œλŠ” μœ μ €κ°€ μ œλŒ€λ‘œ 값듀을 μž…λ ₯ν–ˆλŠ”μ§€ 검증을 ν•΄μ€˜μ•Ό ν•œλ‹€. ν΄λΌμ΄μ–ΈνŠΈμ— μœ μ €κ°€ μž…λ ₯ν•œ 값듀을 μ„œλ²„μ— μ œμΆœν•˜κΈ° 전에 잘λͺ»λœ 값에 λŒ€ν•œ error 문ꡬλ₯Ό λ„μ›Œ λ‹€μ‹œ μž…λ ₯ν•˜κ²Œ μœ λ„ν•œλ‹€λ©΄ μ„œλ²„μ— 잘λͺ»λœ μš”μ²­μ„ ν•˜μ§€ μ•Šμ•„λ„ λ˜μ–΄ νš¨μœ¨μ μ΄λ‹€.

Why do we need react-hook-form library?

error validation 을 직접 κ΅¬ν˜„ν•  μˆ˜λŠ” μžˆλ‹€. useState 둜 μž…λ ₯값듀을 μƒνƒœλ‘œ 관리해 μƒνƒœκ°€ λ³€ν• λ•Œλ§ˆλ‹€ validation 을 ν•΄μ€„μˆ˜λŠ” μžˆλ‹€. κ·Έλ ‡μ§€λ§Œ ν•œ νŽ˜μ΄μ§€μ— μ—¬λŸ¬κ°œμ˜ 검증을 ν•΄μ•Ό ν•˜λŠ” 경우 state 관리가 νž˜λ“€μ–΄μ§€κ³  또 useState νŠΉμ„±μƒ state 값이 λ³€ν•  λ•Œλ§ˆλ‹€ μ»΄ν¬λ„ŒνŠΈκ°€ rerender λ˜μ–΄ λΉ„μš©λ¬Έμ œλ„ λ°œμƒν•  수 μžˆλ‹€.

react-hook-form 은 μ΄λŸ¬ν•œ λΆˆνŽΈν•¨μ„ ν•΄κ²°ν•΄μ£ΌλŠ” λΌμ΄λΈŒλŸ¬λ¦¬μ΄λ‹€.

https://react-hook-form.com/

react hook form image

react hook form image

λ‚΄κ°€ 써보고 λŠλ‚€ React-hook-form 의 μž₯점

  1. useRef λ₯Ό μ‚¬μš©ν•΄ rerender λ˜μ§€ μ•Šλ„λ‘ ν•΄μ€€λ‹€.
  2. validate option 을 μ£Όκ³  (ex: required) 값듀을 κ²€μ¦ν•˜μ—¬ error message λ₯Ό custom ν•˜λŠ” κ²ƒκΉŒμ§€ λ©”μ†Œλ“œλ“€μ„ μ œκ³΅ν•΄μ€€λ‹€.
  3. watch λ“± 값듀을 λͺ¨λ‹ˆν„°λ§ν•΄μ£ΌλŠ” λ©”μ†Œλ“œλ“€μ΄ μžˆμ–΄μ„œ μ œλŒ€λ‘œ μž…λ ₯ν•˜μ˜€λ‹€λŠ” λ“±μ˜ 메세지λ₯Ό μ£Όμ–΄μ•Ό ν• λ•Œλ„ νŽΈλ¦¬ν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλ‹€.

React-hook-form 으둜 error validation ν•˜κΈ°

νšŒμ›κ°€μž… error validation

νšŒμ›κ°€μž… error validation

import { FieldValues, useForm } from "react-hook-form"; const SignUpComponent: React.FC<...> => (...) => { ... const { register, handleSubmit, getValues, watch, formState: { errors, dirtyFields }, } = useForm({ mode: "onSubmit", reValidateMode: "onChange", shouldFocusError: true, }); const watchTerms = watch("terms"); const isInvalidBirthday = getValues("year") === "default" || getValues("month") === "default" || getValues("day") === "default"; const isInputValid = Object.keys(dirtyFields).length > 0 && Object.keys(errors).length === 0 && !isInvalidBirthday && watchTerms === true; const onSubmit = (data: FieldValues) => {...} return (... <form className="w-300" onSubmit={handleSubmit(onSubmit)}> <TextInput label="Email" name="email" register={register} placeholder="Email here" options={{ required: true, maxLength: { value: 50, message: "Max length of 50 is allowed", }, pattern: { value: /^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]/, message: "email format is invalid", }, }} editable={false} errors={errors.email} /> {errors.email?.type === "required" && ( <p className="text-red-500">Please write your email</p> )} <PasswordInput label="Password" name="password" register={register} placeholder="Password here" options={{ required: true, minLength: { value: 8, message: "Minimum 8 letters" }, pattern: { // ν•„μˆ˜: μ•ŒνŒŒλ²³, 숫자 포함 μ˜΅μ…˜: 특수문자 포함 < > μ œμ™Έ value: /^(?=.*[0-9])(?=.*[a-zA-Z])[a-zA-Z0-9!@#$%^&*()]{8,}/, message: "both Alphabets and Numbers", }, }} editable={false} errors={errors.password} /> {getValues("password")?.length >= 8 && !errors.password && ( <span className="text-green-500"> V minimum 8 letters. V both Alphabet and number </span> )} <TextInput label="Username" name="nickname" register={register} placeholder="Username here" options={{ required: true, maxLength: { value: 50, message: "maxLength is 50" }, }} errors={errors.nickname} /> <div className="mb-70"> <div className="flex"> <Select name="year" label="Year" register={register} options={generateNumberArray(1950, 2022)} /> <Select name="month" label="Month" register={register} options={generateNumberArray(1, 12)} /> <Select name="day" label="Day" register={register} options={generateNumberArray(1, 31)} /> </div> {isInvalidBirthday && ( <p className="text-red-500">Please select your birthday</p> )} </div> <span role="button" className="font-bold underline"> Terms and conditions </span> <input type="checkbox" {...register("terms")} /> {watchTerms === false && ( <p className="text-red-500"> Before you sign up, please check here. </p> )} <div className="block mt-20"> <RoundButton width="w-200" height="h-56" type="submit" label="Sign up" disabled={!isInputValid} /> </div> </form>
  1. required ν•„μˆ˜μž…λ ₯ ν•΄μ•Ό ν•˜λŠ”λ° μž…λ ₯ μ•ˆ 된 경우
  • options 에 required: true μ£ΌκΈ°
  • formState errors 객체에 error 메세지 λ“± 정보가 λ“€μ–΄μžˆλ‹€.

react hook form error

react hook form error

{errors.email?.type === "required" && (<p className="text-red-500">Please write your email</p> )}

μ΄λŸ°μ‹μœΌλ‘œ μœ μ €μ—κ²Œ μ•Œλ €μ€„ 수 μžˆλ‹€.

  1. minLength, maxLength
maxLength: { value: 50, message: "Max length of 50 is allowed", }, minLength: { value: 8, message: "Minimum 8 letters" }

options 에 쀄 수 있고, Message 도 custom ν•  수 μžˆλ‹€.

  1. μ •κ·œμ‹ regex
pattern: { // ν•„μˆ˜: μ•ŒνŒŒλ²³, 숫자 포함 μ˜΅μ…˜: 특수문자 포함 < > μ œμ™Έ value: /^(?=.*[0-9])(?=.*[a-zA-Z])[a-zA-Z0-9!@#$%^&*()]{8,}/, message: "both Alphabets and Numbers", },

πŸ’‘πŸ’‘

input 을 ν•΄μ„œ form submit 을 ν•΄μ•Ό ν•˜λŠ” 경우라면 react-hook-form 을 μ‚¬μš©ν•  것을 κ°•λ ₯ μΆ”μ²œν•œλ‹€. λΆˆν•„μš”ν•œ λ¦¬λ Œλ” 방지와 μ‰¬μš΄ validation 이 μ£ΌλŠ” μž₯점이 정말 크닀.

Β© Copyright 2022, yesCoding