본문 바로가기
React

React-Hook-Form 알아보기 - useForm / useFormContext

by 검소한달걀 2024. 6. 28.

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