React - React Hook Form

sarang_daddy·2023년 9월 27일
0

React

목록 보기
21/26
post-thumbnail

React Hook Form

  • React Hook Form (RHF)은 React 기반 애플리케이션에서 폼을 쉽게 관리할 수 있도록 도와주는 라이브러리다.
  • 일반적인 방법으로 Form을 만든다면 매우 많은 state와 검증단계가 필요하다.
  • RHF을 사용한다면 다양한 Input의 상태와 검증을 간단하게 관리할 수 있다.

일반적인 방법의 코드

  • 하나의 input에도 많은 양의 코드가 필요하다.
import { useState } from 'react';

const ToDoList = () => {
  const [toDo, setToDo] = useState('');
  const [toDoError, setToDoError] = useState('');

  const onChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setToDoError('');
    setToDo(value);
  };

  const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    console.log(toDo);
    if (toDo.length < 10) {
      return setToDoError('To do should be longer');
    }
    console.log('submit');
  };

  return (
    <>
      <div>
        <form onSubmit={onSubmit}>
          <input onChange={onChange} value={toDo} placeholder="Write a to do" />
          <button>Add</button>
          {toDoError !== '' ? toDoError : null}
        </form>
      </div>
    </>
  );
};

export default ToDoList;

React Hook Form

설치

npm install react-hook-form

사용방법

1. useForm

  • RHF의 핵심 훅으로 폼과 관련된 여러 메서드와 속성을 가져올 수 있다.
import { useForm } from 'react-hook-form';

const ToDoList = () => {
  const {} = useForm();
  return (
    <>
      <div>
        <form>
          <input placeholder="Write a to do" />
          <button>Add</button>
        </form>
      </div>
    </>
  );
};

export default ToDoList;
  • const {} = useForm() 에서 다양한 메서드(도구)를 사용할 수 있다.
  • register: 입력 요소를 폼에 등록하는 함수
  • handleSubmit: 폼 제출을 처리하는 함수
  • formState: 폼의 상태에 관한 정보를 담고 있다. (예: errors)
  • setError: 수동으로 폼의 오류를 설정하는 함수
  • setValue : 폼 제출 후 입력값을 설정하는 함수

2. register

  • 입력 요소를 RHF에 등록하는데 사용된다.
import { useForm } from 'react-hook-form';

const ToDoList = () => {
  const { register } = useForm();

  return (
    <>
      <div>
        <form>
          <input {...register('toDo')} placeholder="Write a to do" />
          <button>Add</button>
        </form>
      </div>
    </>
  );
};

export default ToDoList;
  • register에는 input에서 사용하던 다양한 속성이 들어있다.
  • input {...register('toDO')}한번으로 전부 적용할 수 있다.
  • 필수입력, 최소 길이 등의 조건 추가가 가능하다.
    <input
      {...register('email', {
        required: 'Email is required',
        minLength: 10,
        pattern: {
          value: /^[A-Za-z0-9._%+-]+@naver.com$/,
          message: 'Only naver.com emails allowed',
        },
      })}
      placeholder="Email"
    />

3. watch

  • 입력 요소의 값을 확인할 때 사용된다.
const ToDoList = () => {
  const { register, watch } = useForm();

console.log(watch())
  • form 입력값들의 변화를 관찰 할 수 있게 해주는 함수

4. handleSubmit

  • 폼 제출을 처리하는 데 사용된다.
  • 인자로 콜백 함수를 받아서 폼이 유효하다면 해당 콜백 함수를 실행한다.
  • 기존의 onSubmit, preventDefault 를 담당한다고 생각하면 된다.
import { useForm } from 'react-hook-form';

const ToDoList = () => {
  const { register, handleSubmit } = useForm();
  // 모든 검증이 끝나면 일어난다.
  const onVaild = (data: any) => {
    console.log(data);
  };

  return (
    <>
      <div>
        <form onSubmit={handleSubmit(onVaild)}>
          <input {...register('email')} placeholder="email" />
          <input {...register('firstName')} placeholder="firstName" />
          <input {...register('lastName')} placeholder="lastName" />
          <input {...register('userName')} placeholder="userName" />
          <input {...register('password')} placeholder="password" />
          <button>Add</button>
        </form>
      </div>
    </>
  );
};

export default ToDoList;

5. formState

  • 폼의 현재 상태와 관련된 정보를 제공한다.
  • isDirty: 사용자가 폼의 어떤 입력 필드라도 변경한 경우 true를 반환
  • isSubmitting: 폼이 현재 제출 중인 경우 true를 반환
  • isValid: 폼이 유효한 경우 true를 반환
  • submitCount: 폼이 제출된 횟수
  • touchedFields: 사용자가 접근하거나 수정한 입력 필드의 목록
  • errors: 폼의 유효성 검사 오류에 대한 정보.
import { useForm } from 'react-hook-form';

const ToDoList = () => {
  const { register, handleSubmit, formState } = useForm();
  // 모든 검증이 끝나면 일어난다.
  const onValid = (data: any) => {
    // console.log(data);
  };

  // formState의 errors 속성 확인
  console.log(formState.errors);

  return (
    <>
      <div>
        <form
          style={{ display: 'flex', flexDirection: 'column' }}
          onSubmit={handleSubmit(onValid)}
        >
          <input
            {...register('email', { required: true })}
            placeholder="email"
          />
          <input
            {...register('firstName', { required: true, minLength: 10 })}
            placeholder="firstName"
          />
          <input
            {...register('lastName', { required: true })}
            placeholder="lastName"
          />
          <input
            {...register('userName', { required: true })}
            placeholder="userName"
          />
          <input
            {...register('password', {
              required: 'Password is required',
              minLength: {
                value: 5,
                message: 'Your password too short',
              },
            })}
            placeholder="password"
          />
          <button>Add</button>
        </form>
      </div>
    </>
  );
};

export default ToDoList;
  • formState의 errors 속성을 이용하면 현재 어떤 input에서 에러가 발생했는지 알 수 있다.

6. errors

  • formState의 errors를 활용해서 사용자에게 잘못된 입력값을 알려 줄 수 있다.
  • register에서 등록한 조건을 충족하지 못한다면 formState의 errors 속성에 등록된다.

errors의 속성

  • type : 오류의 유형. (예: "required", "minLength", "pattern" 등)
  • message : 오류에 대한 메시지. register 함수에서 설정한 오류 메시지나 setError 함수를 통해 수동으로 설정한 오류 메시지를 포함할 수 있다.
  • 특정 register에 errors가 있다면 message를 통해 사용자에게 보여 줄 수 있다.

7. setError

  • 수동으로 입력 필드에 오류를 설정하는 데 사용된다.
  • API 응답 또는 사용자 정의 로직을 기반으로 오류를 설정할 때 유용하다.
setError(name, error, options);
  1. name(필수) : 오류를 설정할 입력 필드의 이름
  2. error(필수) : 설정할 오류의 정보
    • type: 오류의 유형 (예: "manual", "required" 등)
    • message: 오류 메시지
  3. options(선택) : 추가적인 옵션을 설정할 수 있다.
    • shouldFocus: 오류가 설정된 입력 필드로 포커스를 이동할지 결정하는 불리언 값.
  • onValid에 setError를 추가하여 폼 제출전에 검증 단계를 추가할 수 있다.
const onValid = (data: IForm) => {
    if (data.password !== data.rePassword) {
      setError(
        'rePassword',
        { message: 'Password are not the same' },
        { shouldFocus: true },
      );
    }
  };

8. Custom Validation

  • 사용자 정의 유효성 검사로 register 함수의 validate 옵션을 사용해서 정의할 수 있다.
  • 예) 특정 아이디는 사용이 불가하다는 사용자 정의 유효성

9. Pattern VS Validate

pattern

  • pattern은 정규 표현식을 기반으로 입력 값의 형식을 검사한다.
  • 주로 특정 형식(예: 이메일 주소, 전화번호)을 가진 값이 입력되었는지 확인할 때 사용된다.
  • pattern 속성의 값은 정규 표현식과 관련된 오류 메시지를 포함하는 객체가 될 수 있다.

예시:

register('email', {
  pattern: {
    value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
    message: 'Invalid email format'
  }
})

validate

  • validate는 사용자 정의 검증 함수를 제공하여 좀 더 복잡한 유효성 검사를 수행할 수 있다.
  • 함수는 입력 값이 유효한 경우 true 또는 유효하지 않은 경우 오류 메시지를 반환해야 한다.
  • 여러 개의 사용자 정의 검증 함수를 객체 형태로 제공하여 여러 규칙을 동시에 적용할 수 있다.

예시:

register('username', {
  validate: {
    isUnique: value => isUsernameUnique(value) || 'Username is already taken',
    notEmpty: value => value.trim().length > 0 || 'Username cannot be empty'
  }
})

차이점

  • pattern은 정규 표현식을 기반으로 입력 값의 형식을 간단하게 검사하는 데 사용되는 반면, validate는 복잡한 로직이나 여러 검증 규칙을 적용하는 데 사용된다.
  • pattern은 주로 특정 형식의 값이 입력되었는지 확인하는 데 사용되고, validate는 다양한 조건을 기반으로 입력 값을 검증하는 데 사용된다.
profile
한 발자국, 한 걸음 느리더라도 하루하루 발전하는 삶을 살자.

0개의 댓글