관리 메뉴

Gyejoong's Information

React Hook Form 시리즈 포스팅 - 1. React Hook Form 시작하기 본문

Web/React

React Hook Form 시리즈 포스팅 - 1. React Hook Form 시작하기

연계중 2022. 3. 26. 21:45
반응형

React Hook Form 시리즈 포스팅 가장 첫 번째, React Hook Form 시작하기입니다.

이번 포스팅은 아래 순서로 진행이 됩니다.

 

  • 설치
  • 기본 사용법 설명
  • DevTool 사용하기
  • UI 라이브러리와 함께 사용하기
  • 에러 처리

 

 설치

현재 진행 중인 프로젝트에 아래와 같은 명령어를 입력합니다.

npm install react-hook-form

 

yarn을  사용한다면 아래와 같이 입력합니다.

 yarn add react-hook-form

 

기본 사용법  설명

기본 예제

import React from 'react';
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'));

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input defaultValue="test" {...register('example')} />

      <input {...register('exampleRequired', { required: true })} />
      {errors.exampleRequired && <span>This field is required</span>}

      <input type="submit" />
    </form>
  );
}

 

기본 사용법은 사용하려는 form에 useForm hooks를 선언합니다.

form의 onSubmit 핸들러에 react hook form의 handleSubmit으로 wrapping 합니다.

이는 form 자체의 onSubmit이 호출되기 전 상위 레벨에서 유효성 검사를 하고 난 후, data를 넘겨주기 위함입니다.

 

위 예제에서, exampleRequired라는 필드에  required: true 옵션이 정의되어 있으므로 해당 필드에 입력되지 않고, submit을 하면 form의 onSubmit이 호출되기 전에 유효성 검사에서 errors에 exampleRequired 속성에 데이터가 바인딩되어 리 렌더링이 발생하여 This field is required라는 텍스트가 렌더링 됩니다.

 

watch 메서드는 필드의 값이 변경될 때마다 리 렌더링이 되어, 실시간으로 데이터 변경을 감지할 수 있는 메서드입니다. 

 

regsiter field의 핵심은 register(name)에서 name을 지정해야 하며, component 내부에 선언되어야 합니다. 상세한 validation option은 아래 챕터에서 알아봅시다.

 

Validation Option

아래 목록에 validation option이 있습니다.

  • required 필수 값 여부 (boolean)
  • min 최소 값 (number)
  • max 최대 값 (number)
  • minLength 값의 최소 길이 (number)
  • maxLength 값의 최대 길이 (number)
  • pattern 입력에 대한 정규식 패턴 (RegExp)
  • validate 다른 유효성 검사 규칙에 의존하지 않고 실행되는 옵션. 콜백 함수를 정의하거나 콜백 함수가 포함된 객체를 정의할 수 있습니다.
import React from 'react';
import { useForm, SubmitHandler } from 'react-hook-form';

interface IFormInput {
  firstName: string;
  lastName: string;
  agreement: string;
  nickname: string;
  age: number;
}

const checkNickname = (nickname: string) => {
  if (nickname.includes('Master')) {
    return false;
  }

  return true;
};

export default function App() {
  const { register, handleSubmit } = useForm<IFormInput>();
  const onSubmit: SubmitHandler<IFormInput> = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('firstName', { required: true, maxLength: 20 })} />
      <input {...register('lastName', { pattern: /^[A-Za-z]+$/i })} />
      <input
        {...register('agreement', { validate: (value) => value === '1' })}
      />
      <input
        {...register('nickname', {
          validate: {
            positive: (v) => v.length > 0,
            lessThanTen: (v) => v.length < 10,
            checkNickname: (v) => checkNickname(v)
          }
        })}
      />
      <input type="number" {...register('age', { min: 18, max: 99 })} />
      <input type="submit" />
    </form>
  );
}

 

위의 예제에서 agreement라는 필드에 지정된 validate 옵션에 value가 '1'인 경우에만 유효성 검사가 통과되도록 정의를 해두었습니다. 1이라는 text 이외에 다른 값은 입력이 불가능하게 됩니다. 

 

추가로 nickname 필드를 보게 되면, validate 옵션에 object로 3가지의 유효성이 정의가 되어 있습니다. 길이가 0보다 크고, 10보다 작으며, Master 가 포함된 nickname은 입력할 수 없게 됩니다.

 

Dev Tool 사용하기

dev tool 설치

현재 진행 중인 프로젝트에 아래와 같은 명령어를 입력합니다.

npm install @hookform/devtools

 

yarn을  사용한다면 아래와 같이 입력합니다.

yarn add @hookform/devtools

 

사용법

import React from "react";
import { useForm } from "react-hook-form";
import { DevTool } from "@hookform/devtools";

export default () => {
  const { register, control, handleSubmit } = useForm({
    mode: "onChange",
  });

  return (
    <>
      <form onSubmit={handleSubmit(d => console.log(d))}>
        <h1>React Hook Form DevTools</h1>

        <label>Test</label>
        <input {...register("test")} />

        <input type="submit" />
      </form>
      
      <DevTool control={control} /> {/* dev tool 정의 */}
    </>
  );
};

 

DevTool를 설치 후, 정의하면 위의 이미지와 같이 우측에 Bar가 노출이 됩니다.

 

UI 라이브러리와 같이 사용하기

예제를 살펴 보기전 아래와 같이 명령어를 입력합니다.

npm install @mui/material @emotion/react @emotion/styled react-select

 

yarn을 사용한다면  아래와 같이 입력합니다.

yarn add @mui/material @emotion/react @emotion/styled react-select

 

import React from 'react';
import Select from 'react-select';
import { useForm, Controller, SubmitHandler } from 'react-hook-form';
import { Input } from '@mui/material';

interface IFormInput {
  firstName: string;
  lastName: string;
  iceCreamType: { label: string; value: string };
}

const App = () => {
  const { control, handleSubmit } = useForm<IFormInput>();

  const onSubmit: SubmitHandler<IFormInput> = (data) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Controller
        name="firstName"
        control={control}
        defaultValue=""
        render={({ field }) => <Input {...field} />}
      />
      <Controller
        name="iceCreamType"
        control={control}
        render={({ field }) => (
          <Select
            {...field}
            options={[
              { value: 'chocolate', label: 'Chocolate' },
              { value: 'strawberry', label: 'Strawberry' },
              { value: 'vanilla', label: 'Vanilla' }
            ]}
          />
        )}
      />
      <input type="submit" />
    </form>
  );
};

export default App;

 

UI 라이브러리와 같이 사용할때는 Controller 컴포넌트를 사용해야 합니다. render props를 활용해서 컨트롤 합니다.

 

에러 처리

아래 예제를 보기 전, error message를 좀 더 손쉽게 관리해주는 라이브러리를 다운로드하여 봅시다.

npm install @hookform/error-message

 

yarn을  사용한다면 아래와 같이 입력합니다.

yarn add @hookform/error-message

 

예제

import React from 'react';
import { useForm, SubmitHandler } from 'react-hook-form';
import { ErrorMessage } from '@hookform/error-message';

interface IFormInputs {
  firstName: string;
  lastName: string;
  singleErrorInput: string;
}

const onSubmit: SubmitHandler<IFormInputs> = (data) => console.log(data);

export default function App() {
  const {
    register,
    formState: { errors },
    handleSubmit
  } = useForm<IFormInputs>();

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('firstName', { required: true })} />
      {errors.firstName && 'First name is required'}
      <input {...register('lastName', { required: true })} />
      {errors.lastName && 'Last name is required'}
      <input
        {...register('singleErrorInput', { required: 'This is required.' })}
      />

      <ErrorMessage errors={errors} name="singleErrorInput" />

      <ErrorMessage
        errors={errors}
        name="singleErrorInput"
        render={({ message }) => <p>{message}</p>}
      />

      <input type="submit" />
    </form>
  );
}

firstName과 lastName의 필드를 입력하지 않으면, errors 객체의 각 필드네임으로 바인딩되어 리 렌더링이 발생합니다.

그렇게 되면, First name is required와 Last name is required 텍스트가 출력되겠지요.

 

singleErrorInput은 위와 조금 다른데요. required에는 boolean 뿐만 아니라 string도 입력이 가능합니다. error가 발생했을 때 해당 string값이 바로 출력이 되는데요.

이때, ErrorMessage 컴포넌트가 유용하게 사용됩니다. errors 객체와 name만 props로 넘기면 에러 메시지가 렌더링이 됩니다.

 

ErrorMessage 컴포넌트에는 render props가 존재하는데요. 출력되는 메시지의 스타일을 변경하거나 별도의 컴포넌트로 렌더링 할수 있도록 제공되는 props입니다. 

 

마치며

이번 포스팅은 여기까지입니다. React Hook Form의 기본을 이해하는데 많은 도움이 되었으면 합니다. 감사합니다.

 

다음 포스팅 - 기본 API 소개
반응형

'Web > React' 카테고리의 다른 글

React Hook Form 시리즈 포스팅 - React Hook Form이란?  (0) 2022.03.19
Comments