react-hook-form 에서 useFormContext 사용하기 (react form에서 props driiling을 막아보자)
저번에 react-hook-form을 사용해서 회원가입과 로그인 폼을 변경했었는데 입력 필드의 유효성 검사라던지, 전송 데이터를 자동으로 객체화해주는 점 등은 너무나 편리하고 맘에 들었다. useForm 적용하는 법이 궁금하신 분들은 이전 글을 참고해주세용
https://coding-frog.tistory.com/25
그렇지만 기존의 문제였던 props drilling의 문제가 여전히 계속되고 있었다 ㅠㅠ
useform으로 변경한 후에 변경하는 값들을 일일히 state로 저장할 필요는 없었지만 register 함수와 errors 객체는 모든 컴포넌트에서 공유하기 위해서 다 내려보내줘야 했기 때문에 이렇게 지저분한 코드가 완성되었다.
이렇게 되면 props drilling 면에서는 이전 코드와 별다를게 없었다.
그러다가 완전 form 에서 쓸수 있는 useContext인 useFormContext 가 있다는 걸 알았다. 이걸 쓰면 useForm 에서 쓰는 모든 메소드들을 상태관리할 수 있다. 그래서 모든 필드에 register같은 메소드를 내려보낼 필요가 없다. useForm 은 이런 기능도 있고 진짜 갓벽한 훅이다 다들 이걸 써주세요 ~~!!
그래서 어떻게 쓰나면요..
useFormContext 쓰는 방법
1. useForm에서 쓰는 메소드 정의
const methods = useForm();
일단 이렇게 useForm() 에서 쓰는 모든 메소드들을 객체로 가져올 수 있다. 이렇게 정의해준다. 이름은 methods 말고 아무거나 해도 상관없다.
methods를 콘솔에 찍어보면 이렇게 모든 메소드들이 객체에 들어있는 걸 볼수 있다.
2. Form 역할을 하는 컴포넌트 감싸기
그리고 form 컴포넌트를 <FormProvider>로 감싸주면 된다. 당연히 import 해와야 한다.
import { useForm, FormProvider } from 'react-hook-form'
이렇게 폼 전체를 FormProvider로 감쌌다.
그러면 이제 FormProvider 아래에 있는 모든 컴포넌트에서 methods를 사용할 수 있다. 따로 보내주지 않아도 된다.
그리고 하위 컴포넌트 말고 이 컴포넌트 안에서 메소드들을 쓰고 싶다면 methods.handleSubmit 이런 식으로 쓰면 된다. 아니면 특정한 메소드만 methods에서 따로 빼서 정의해주면 바로 쓸 수 있다. 나는 따로 정의했다.
const methods = useForm();
const {handleSubmit, formState : {isSubmitting}} = methods;
이 컴포넌트에서는 handleSubmit 이랑 isSubmitting만 쓸것이기 때문에 이렇게 정의해줬다.
3. methods 넘겨주기
정의한 method 객체를 한번에 넘겨준다.
4. 하위 컴포넌트에서 사용할 메소드 정의하기
하위컴포넌트에서 useFormContext를 import 해주면 보내준 methods 를 가져올 수 있다. 이 methods 에서 사용할 메소드를 뽑아서 선언해주면 된다. 나는 하위컴포넌트에서 필드 등록을 위해 register랑, 에러처리를 위해 errors 속성을 가져왔다.
import { useFormContext } from 'react-hook-form'
const {register, formState : {errors}} = useFormContext();
그러면 이제 그냥 사용하면 된다.
사용 예시다. 원래는 ...props.register 로 등록해야 했는데 이제 props 없이 ...register 사용이 가능하다.
최종 결과
문제의 코드가 훨씬 깔끔해졌다!