본문 바로가기
React/실험실

[React] useForm

by 잉여개발자 2023. 3. 5.

form 형식의 페이지에 상태를 관리하는 것은 생각보다 귀찮은 작업이다. 

form에 개수에 맞춰서 state를 만들어주고, reset이 필요한 경우 state의 개수만큼 값을 초기화해야 한다. 

 

불편한 점은 이것만이 아니다. 

값의 검증, 또는 onChange 이벤트 시에도 상태의 수만큼 만들어줘야한다. 

 

결국 유사한 코드가 반복되는 상황이 발생하는 것이다. 

이것을 비교적 간단하게 처리해주는 커스텀 훅이 useForm이다. 

 

useForm? 

앞서 말한 것처럼 쉽게 form을 관리할 수 있는 커스텀 훅이다. 

npm install react-hook-form

다음과 같은 방법으로 설치할 수 있다. 

 

굳이 useForm을 사용해야 하는 이유를 먼저 설명하자면, 

값의 변경, submit, 조회, 오류 검출 등의 기능을 상태 하나에 귀속되는 것이 아닌 form에 필요한 모든 상태를 

useForm 한번으로 처리가 가능하다. 

 

사용해보기

import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, watch, formState: { errors } } = useForm();
  const onSubmit = 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>
  );
}

공식 사이트에서 알려주는 예제이다. 

 

form 안에는 example과 exampleRequired 라는 명칭의 input이 2개 존재한다. 

이것을 개별로 관리하는 것이 아닌, useForm 하나를 통해서 모두 관리하고 있다. 

 

const { register, handleSubmit, watch, formState: { errors } } = useForm();

더 많은 속성이 있지만 여기 있는 것을 설명하자면, 

 

useForm 

예시에서는 매개변수로 아무것도 넘기지 않지만, defaultValue를 넘겨줄 수 있다. 

useForm({
  defaultValues: {
    firstName: '',
    lastName: ''
  }
})

다음과 같이 defaultValues를 넘겨주면 해당 값으로 초기화된  값을 받아올 수 있다. 

 

register 

상태를 변경하기 위해서 사용하는 함수이다. 

<input defaultValue="test" {...register("example")} />

register는 onChange, onBlur, ref, name을 가지고 있고, 

매개변수를 통해서 해당 form의 onChange 등을 넘겨준다. 

 

또한 두 번째 매개변수로 더 많은 것을 지원한다. 

...register("example", {
    /* option */
})

required : 이름 그대로 필수 요소를 나타낸다. 

                required를 true로 줄 경우 submit 이벤트가 발생할 때 값이 비어있다면 error를 받아온다. 

                input에서의 required 옵션이라고 생각하면 된다. 

 

maxLength : input의 최대 길이를 나타낸다. 

 

pattern : 정규 표현식을 넘겨야하며, input의 값이 해당 표현식에 통과하지 않으면 error를 받아온다. 

 

외에도 max, min, minLength , ... 등 많은 옵션을 지원한다. 

 

handleSubmit 

submit 이벤트를 할당시켜주는 함수이다. 

 <form onSubmit={handleSubmit(onSubmit)}>

실제 submit이 발생했을 때 실행되어야 할 함수를 매개변수로 form에 넘겨주면 

내부적으로 useForm의 값을 확인하고 함수를 실행시켜 준다. 

 

이때, 상태 값은 handleSubmit에서 data로 함수에 넘겨준다. 

그래서 submit 함수에서 data를 통해서 간단하게 처리가 가능하다. 

handleSubmit(async (data) => await fetchAPI(data))

 

그리고 앞서 register에서 설정한 pattern, required 등을 실제 값에 비교를 해서 만약 통과하지 못한다면, 

submit은 실행되지 않고 formState의 errors에 해당 오류를 넘겨준다. 

 

watch 

form에서 원하는 값을 조회 또는 form의 모든 값을 조회하는 경우 사용된다. 

  console.log(watch("example"));

매개 변수로 input의 명칭을 넣어주면 해당 값을 반환시켜주는 함수이다. 

또는 빈 값만 사용한다면 모든 form의 값을 얻어올 수 있다. 

 

formState

form의 다양한 상태를 return 한다. 

가장 많이 사용하는 것이 errors라고 생각한다. 

 

register를 통해서 설정해둔 값이 handleSubmit을 통해 통과하지 않으면 errors를 통해서

해당 상태의 명, 에러 종류(required, pattern .. ) 등을 얻게된다. 

 

이것으로 간단하게 form에서 error 메시지를 넘겨줄 수 있다. 

 

이것 외에도 정말 많은 옵션이 있다. 

하지만 이것을 모두 설명하지 않고 공식 사이트의 링크를 올려두겠다. 

 

필요한 경우 해당 사이트를 참고하면 좋을 것 같다. 

https://react-hook-form.com/api/useform/

 

useForm

Performant, flexible and extensible forms with easy-to-use validation.

react-hook-form.com

 

반응형

'React > 실험실' 카테고리의 다른 글

[React] styled-components theme  (0) 2023.03.20
[React] swiper 부드럽게 흐르는 슬라이드  (0) 2023.03.15
[React] redux-persist  (1) 2023.02.11
[React] Compound Component 패턴  (1) 2023.02.04
[React] Context Module Function 패턴  (0) 2023.02.02

댓글