[React] react-hook-form μΌλ‘ input validation νκΈ°
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 μ μ₯μ
- useRef λ₯Ό μ¬μ©ν΄ rerender λμ§ μλλ‘ ν΄μ€λ€.
- validate option μ μ£Όκ³ (ex: required) κ°λ€μ κ²μ¦νμ¬ error message λ₯Ό custom νλ κ²κΉμ§ λ©μλλ€μ μ 곡ν΄μ€λ€.
- watch λ± κ°λ€μ λͺ¨λν°λ§ν΄μ£Όλ λ©μλλ€μ΄ μμ΄μ μ λλ‘ μ λ ₯νμλ€λ λ±μ λ©μΈμ§λ₯Ό μ£Όμ΄μΌ ν λλ νΈλ¦¬νκ² μ¬μ©ν μ μλ€.
React-hook-form μΌλ‘ 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>
- required νμμ λ ₯ ν΄μΌ νλλ° μ λ ₯ μ λ κ²½μ°
- options μ required: true μ£ΌκΈ°
- formState errors κ°μ²΄μ error λ©μΈμ§ λ± μ λ³΄κ° λ€μ΄μλ€.
react hook form error
{errors.email?.type === "required" && (<p className="text-red-500">Please write your email</p> )}
μ΄λ°μμΌλ‘ μ μ μκ² μλ €μ€ μ μλ€.
- minLength, maxLength
maxLength: { value: 50, message: "Max length of 50 is allowed", }, minLength: { value: 8, message: "Minimum 8 letters" }
options μ μ€ μ μκ³ , Message λ custom ν μ μλ€.
- μ κ·μ 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 μ΄ μ£Όλ μ₯μ μ΄ μ λ§ ν¬λ€.