React-Hook-Form은 간단하고 효율적으로 폼 관리를 할 수 있는 라이브러리다.
이전에는 아래와 같이 폼 입력값들을 전부 useState와 onChange를 사용해 값을 실시간으로 가져오고 관리했었다.
const emailRegEx =
/^[A-Za-z0-9]([-_.]?[A-Za-z0-9])*@[A-Za-z0-9]([-_.]?[A-Za-z0-9])*\.[A-Za-z]{2,3}$/i;
const passwordRegEx = /^.{8,}$/;
const SignUpForm = ({ setFormType, onClose }) => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [checkPassword, setCheckPassword] = useState('');
const [foundAnswer, setFoundAnswer] = useState('');
const [name, setName] = useState('');
const [region, setRegion] = useState('');
const [checkEmailText, setCheckEmailText] = useState('');
const [checkPasswordText, setCheckPasswordText] = useState('');
const [checkPasswordReg, setCheckPasswordReg] = useState('');
const [isFormValid, setIsFormValid] = useState(false);
.
.
.
<LongInput
title='이메일'
type='email'
placeholder='이메일 입력'
value={email}
onChange={(e) => {
setEmail(e.target.value);
emailCheck(e.target.value);
}}
checkText={checkEmailText}
/>
<LongInput
title='비밀번호'
type='password'
placeholder='비밀번호 입력'
value={password}
onChange={(e) => {
setPassword(e.target.value);
passwordRegCheck(e.target.value);
}}
checkText={checkPasswordReg}
/>
개발할 땐 몰랐는데 정말 비효율적인 코드였다..🙄
반면 React-Hook-Form은 비제어 폼으로,
input의 ref 객체를 참조하여 입력할 때마다 발생하는 불필요한 재렌더링을 줄이고 작성해야 하는 코드도 간결하다.
설치
npm install react-hook-form
공식 홈페이지
Get Started
Performant, flexible and extensible forms with easy-to-use validation.
react-hook-form.com
import { useForm, SubmitHandler } from "react-hook-form"
type Inputs = {
example: string
exampleRequired: string
}
export default function App() {
const {
register,
handleSubmit,
watch,
formState: { errors },
} = useForm<Inputs>()
const onSubmit: SubmitHandler<Inputs> = (data) => console.log(data)
console.log(watch("example")) // watch input value by passing the name of it
return (
/* "handleSubmit" will validate your inputs before invoking "onSubmit" */
<form onSubmit={handleSubmit(onSubmit)}>
{/* register your input into the hook by invoking the "register" function */}
<input defaultValue="test" {...register("example")} />
{/* include validation with required or other standard HTML validation rules */}
<input {...register("exampleRequired", { required: true })} />
{/* errors will return when field validation fails */}
{errors.exampleRequired && <span>This field is required</span>}
<input type="submit" />
</form>
)
}
공식 홈페이지에 있는 간단한 예시를 보면,
1. register
입력 필드를 등록하고 React-Hook-Form에 유효성 검사 규칙을 적용할 수 있도록 한다.
2. handleSubmit
유효성 검사를 수행하고 폼 제출을 처리한다.
3. watch
입력 필드의 값을 실시간으로 관찰하고 필요에 따라 getValues를 이용해 현재 값을 가져올 수 있다.
4. formState
입력 필드의 값, 오류 상태, 제출 상태 등 폼의 상태를 나타낸다.
useFormState | |
errors | 입력 필드의 이름을 키로 카지고 유효성 검사 실패 시 발생하는 오류를 관리 |
isDirty | 폼이 수정되었는지 여부 판별 |
isValid | 현재 폼의 유효성 상태 |
isSubmitting | 폼이 현재 제출 중인지 여부 확인 (제출 중복 방지에 활용) |
touchedFields | 사용자가 포커스를 준 입력 필드 목록 |
dirtyFields | 사용자가 수정한 입력 필드 목록 |
이외에도 다양한 useForm의 props들이 있다.
useForm의 Props |
||
reset | 입력 필드 초기값 설정 | reset({ firstName: "John" }); |
resetField | 특정 필드의 상태를 초기화 | resetField("firstName"); |
clearErrors | 특정 필드의 오류를 제거 | clearErrors("firstName"); |
setValue | 특정 필드의 값을 설정 | setValue("firstName", "John"); |
setFocus | 특정 필드에 포커스를 설정 | setFocus("firstName"); |
getValues | 폼의 현재 값을 가져옴 | const values = getValues(); |
getFieldState | 특정 필드의 상태를 가져옴 | const fieldState = getFieldState("firstName"); |
trigger | 특정 필드의 유효성 검사를 수동으로 진행 | trigger("firstName"); |
useFormContext
import React from "react"
import { useForm, FormProvider, useFormContext } from "react-hook-form"
export default function App() {
const methods = useForm()
const onSubmit = (data) => console.log(data)
return (
<FormProvider {...methods}>
// pass all methods into the context
<form onSubmit={methods.handleSubmit(onSubmit)}>
<NestedInput />
<input type="submit" />
</form>
</FormProvider>
)
}
function NestedInput() {
const { register } = useFormContext() // retrieve all hook methods
return <input {...register("test")} />
}
useFormContext는 useForm에서 쓰는 메소드들을 일일이 내려보낼 필요 없이 상태관리할 수 있게 한다.
1. const methods = useForm()
useForm에서 쓰는 모든 메소드들을 객체로 가져온다.
2. <FormProvider {...methods}> </FormProvider>
form 컴포넌트를 <FormProvider>로 감싸준다.
그러면 하위에 있는 모든 form 컴포넌트에서 아래와 같은 방식으로 메소드들을 사용할 수 있다.
const {register, formState : {errors}} = useFormContext();
'React' 카테고리의 다른 글
AWS S3 presignedURL을 이용한 이미지 파일 업로드 (0) | 2024.08.30 |
---|