프론트엔드/React.js

React-Hook-Form

lifecarelog 2022. 9. 10. 20:42
반응형

React Hook Form

  • 사용하기 쉬운 유효성 검사를 통해 성능이 뛰어나고 유연하며 확장 가능한 form입니다.

Home

설치

npm install react-hook-form

or

yarn add react-hook-form
  • 설치시 에러가 날 수 있다 ⇒ react-hook-form이 현재 react 16 or 17 버전만 지원
    • 에러가 난다면 ⇒ 설치 명령어 뒤에 --legacy-peer-deps 옵션을 붙여 준다.
    • 현재는 18버전도 지원

위 라이브러리 없이 form 형식을 구현한다면 각각의 사용자 입력 요소마다 value, errorMsg state가 필요하고 handleFunc이 필요하다.

또한 form요소의 onSubmit 함수에는 각각의 사용자 입력 요소별로 validation check 로직을 작성해야 한다.

const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');

const [formErrors, setFormErrors] = useState('');
const [emailError, setEmailError] = useState('');
const [passwordError, setPasswordError] = useState('');

const onUsernameChange = (event: React.SyntheticEvent<HTMLInputElement>): void => {
	const {
	  currentTarget: { value },
	} = event;
	setUsername(value);
};

const onEmailChange = (event: React.SyntheticEvent<HTMLInputElement>): void => {
	const {
	  currentTarget: { value },
	} = event;
	setEmailError('');
	setEmail(value);
};

const onPasswordChange = (event: React.SyntheticEvent<HTMLInputElement>): void => {
	const {
	  currentTarget: { value },
	} = event;
	setPassword(value);
};

const onSubmit = (event: React.SyntheticEvent<HTMLFormElement>): void => {
    event.preventDefault();
    if (username === '' || email === '' || password === '') {
      setFormErrors('All fields are required');
    }
    if (!email.includes('@')) {
      setEmailError('email is required');
    }
		.... validation check 로직 작성
  };

위와 같이 input이 3개인데 작성해야하는 코드 수가 많아진다. form요소를 다룰때 작성해야 할 것들이 매우 많다!

react-hook-form을 사용하면

  1. 더 적은 코드로 작성 할 수 있다.
  2. validation check를 보다 더 나은 방법으로 더 많은 컨트롤을 할 수 있다.
  3. 에러를 설정하고 초기화 할 수 있다.
  4. input들의 컨트롤이 가능하다.
  5. dom event를 직접 다루지 않아도 된다.

사용법

  • 모든 기능은 useForm Hook안에 있다!!

register

register: (name: string, RegisterOptions?) => ({ onChange, onBlur, name, ref })

  • name : input의 name이 된다. , 고유한 name 값을 넣어준다.
  • required: string | { value: boolean, message: string}
    • ex) < input {...register("test", {required: 'error message' })}/>
    • required만 추가해준다고 react-hook-form이 validation 체크를 해주진않고 handleSubmit과 함께 사용해야 한다.

input을 state와 연결시켜주는 역할을 한다.

이 메서드를 사용하면 input을 등록하거나 엘리먼트를 선택하고 React Hook Form에 유효성 검사 규칙을 적용할 수 있다.

유효성 검사 규칙은 모두 HTML 표준을 기반으로 하며 사용자 지정 유효성 검사 방법도 허용한다.

watch

form을 보게 해주는 함수이다.

form이 register 함수에 입력한 이름을 key로 가지는 객체 형태가 됐고 value는 form안에 있는 input에 입력한 값이 된다.

watch함수의 인자로 특정 필드의 name을 넣어주면 특정 필드만 볼 수도 있다.

watch(”email”)

validation

handleSubmit

인자로 2개의 함수를 받는다.

규칙만 정해서 react-hook-form한테 알려주면 알아서 validation 체크를 한다.

이 함수는 form 유효성 검사가 성공하면 form 데이터를 수신합니다.

  • ex) < form onSubmit={handleSubmit(onSubmit, onError)} />

onSubmit (SubmitHandler) (성공적인 콜백)

  • (data: Object, e?: Event) => void
  • 유효한 값을 인자로 받는다.

onError (SubmitErrorHandler) (오류 콜백)

  • (errors: Object, e?: Event) => void
  • 에러를 인자로 받는다 (에러의 타입은 FieldErrors)
  • error 객체에는 에러의 타입을 나타내는 type속성과 사용자가 설정한 에러메시지 message속성과 ref 속성을 갖는다.
email: {type: 'required', message: '', ref: input}
password: {type: 'required', message: '', ref: input}
username: {type: 'required', message: '', ref: input}

register 함수의 2번째 인자로 넣어준 required 옵션에 boolean값이 아닌 string 값으로 넣어주고 싶은 메시지를 넣어주면 에러가 발생했을 때 해당 메시지를 에러 메시지로 사용한다.

register함수의 validate 옵션

  • 커스텀 validation을 만들고 싶을 때 사용한다.

useForm - register

<input
        {...register('username', {
          validate: value => value === '1'
        })}
        type="text"
        placeholder="Username"
      />

mode: onChange | onBlur | onSubmit | onTouched | all = 'onSubmit'

유효성 검사를 하는 시점을 정할 수 있다.

submit버튼을 클릭했을 때 검사를 할건지 아니면 데이터를 입력하면 바로 유효성 검사를할 건지 등을 정할때 사용

기본값은 onSubmit

이 옵션을 사용하면 사용자가 form을 제출하기 전에 유효성 검사를 할 수 있습니다(onSubmit 이벤트).

useForm

onSubmit

Submit버튼을 누르면 그 때 유효성 검사를 한다.

onBlur

값을 입력하던 input에서 focus가 없어질 때 유효성 검사를 한다.

onChange

input의 값이 변화하면 유효성 검사를 한다.

onTouched

유효성 검사는 첫 번째 blur 이벤트에서 트리거됩니다. 그 후에는 모든 change 이벤트에서 트리거됩니다.

all

blur 및 change 이벤트에서 유효성 검사가 트리거됩니다.

formState

  • 객체 형태이다.
  • formState객체의 errors속성을 이용해서 error 메시지를 유저에게 보여줄 수 있다.

setError()

이 함수를 사용하면 하나 이상의 오류를 수동으로 설정할 수 있습니다.

form의 전역 에러를 설정할 수도 있다.

setError("username", {

type: "manual",

message: "Dont Forget Your Username Should Be Cool!"

});

setError("error", {

message: "Backed Form Errors~"
});

useForm - setError

reset()

전체 form state 또는 form state의 일부를 리셋합니다.

(form에서 submit후, 전체 input 초기화할 때 사용 가능)

resetField

개별 field state를 재설정합니다.

(form에서 submit후, 특정 input만 초기화할 때 사용 가능)

import { FieldErrors, useForm } from 'react-hook-form';

interface LoginForm {
  username: string;
  password: string;
  email: string;
  errors?: string;
}

export default function Forms() {
  const {
    register,
    handleSubmit,
    formState: { errors },
    watch,
    setError,
    setValue,
    reset,
    resetField,
  } = useForm<LoginForm>({
    mode: 'onChange',
  });
  const onValid = (data: LoginForm) => {
    console.log('im valid bby');
  };
  const onInvalid = (errors: FieldErrors) => {
    console.log(errors);
  };

  return (
    <form onSubmit={handleSubmit(onValid, onInvalid)}>
      <input
        {...register('username', {
          required: 'Username is required',
          minLength: {
            message: 'The username should be longer than 5 chars.',
            value: 5,
          },
        })}
        type="text"
        placeholder="Username"
      />
      {errors.username?.message}
      <input
        {...register('email', {
          required: 'Email is required',
          validate: {
            notGmail: (value) => !value.includes('@gmail.com') || 'Gmail is not allowed',
          },
        })}
        type="email"
        placeholder="Email"
      />
      {errors.email?.message}
      <input {...register('password', { required: 'Password is required' })} type="password" placeholder="Password" />
      <input type="submit" value="Create Account" />
      {errors.errors?.message}
    </form>
  );
}
반응형