react-hook-form은 리액트에서 폼을 쉽게 관리하고 유효성 검사를 도와주는 라이브러리이다.(물론 유효성 검사는 zod를 이용했다)
이는 react-hook-form의 핵심 훅으로 이 훅을 통해 폼의 입력값, 에러메시지, submit핸들러 등을 관리한다.
const schema = z.object({ // 스키마 zod로 정의
page: z.string().min(1, "1자 이상 입력하세용"),
});
type FormType = z.infer<typeof schema>; // zod 타입 추론
const ReactHookFormBasic = () => {
const [params] = useSearchParams();
const methods = useForm<FormType>({ // hook-form의 CORE
resolver: zodResolver(schema),
defaultValues:{
page: params.get('page') || '0'
}
});
...
useForm의 resolver는 유효성 검사를 위한 옵션으로, zodResolver를 통해 zod와 같은 서드파티 라이브러리와 통합하여 스키마 기반의 유효성 검사를 수행.
(import { zodResolver } from "@hookform/resolvers/zod")
defaultValues는 폼의 초기값을 설정하는 옵션.
register메서드는 폼 필드를 등록하는데 사용된다
...
const navigate = useNavigate();
const location = useLocation();
const onValid: SubmitHandler<FormType> = (values) => {
// alert(values.page);
navigate({
pathname: location.pathname,
search: `?page=${values.page}`,
});
};
const onInvalid: SubmitErrorHandler<FormType> = (errors) => {
// alert(errors.page?.message)
}; // validation 에러시에 실행됨 => zod사용
const inputMethods = methods.register("page"); // inputMethods등록
onValid와 onInvalid는 폼의 제출 즉, onSubmit의 handleSubmit에 넣어줄 수 있는 유효성 검사 성공, 실패 시의 각각 다른 핸들러를 실행하기 위한 함수이다.
여기까지 zod의 유효성검사와 react-hook-form을 연결짓고, 인풋 폼 필드를 useForm에 최종 register까지 한 상태이다.
이걸 어떻게 다루는지 살펴보자.
...
const { data } = useQuery({
queryKey: ['pokeList', params.get('page')],
queryFn: () => {
return fetch(`https://pokeapi.co/api/v2/pokemon?limit=10&offset=${Number(params.get('page')) || 0}`)
.then(res => res.json())
}
})
return (
<> // handleSubmit : 폼 제출시에 성공,실패여부에 따라 실행
<form onSubmit={methods.handleSubmit(onValid, onInvalid)}>
<input
name={inputMethods.name}
ref={inputMethods.ref}
onChange={inputMethods.onChange}
onBlur={inputMethods.onBlur} // input메서드 필수 요소들 4개
/>
<ErrorMessage
errors={methods.formState.errors}
name={inputMethods.name}
/>
<button type="submit">Submit</button>
<button type="submit" onClick={() => methods.reset({
page:'0'// 새로운 값을 (defaultValue) 넣어서 리셋시킨다.
})}>Reset</button>
</form>
{JSON.stringify(data)}
</>
);
};
export default ReactHookFormBasic;
input속성에 필수 요소들 4개를 명시에줘야 hook-form이 정상 작동한다.
혹은 스프레드 연산자로 register메서드의 반환 객체를 넣어줘도 됨
<input {...inputMethods}/>
의 경우 "@hookform/error-message"를 통해 사용할 수 있으며, error, name프로퍼티를 설정해서 유효성 검사에 실패했을 때 에러메시지를 출력할 수 있다.