Frontend

react-hook-form 에서 useFormContext 사용하기 (react form에서 props driiling을 막아보자)

코구리 2023. 9. 6. 23:18

저번에 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 사용이 가능하다.

 

최종 결과

문제의 코드가 훨씬 깔끔해졌다!