Electronic Jeremy Record

[React] React Hook Form으로 Form Validation 쉽게 하기 본문

기술의기록

[React] React Hook Form으로 Form Validation 쉽게 하기

Jeremy Winchester 2022. 3. 13. 23:09
반응형

웹 개발, 특히 프론트앤드 개발을 하다 보면 Form Control을 할 일이 자주 있다.

로그인, 회원 가입, 게시물 작성 등 꽤 자주 활용하게 된다. 

 

보통 Form에 입력된 값들은 DB에 넣거나 조회하는 등 할 때 사용되는데 

Submit 하기 전에 입력을 제대로 했는지, 빠진 값들은 없는지 하는 Validation 과정을 거친다. 

 

이런 일련의 과정들을 매우 쉽게 구현할 수 있는 것이 있어 소개하고자 한다. 

"React Hook Form"

이다. 

 

React Hook Form 의 장점은 

1. 코드 량이 적다.

2. Validation이 강력하다.

3. Error 잡기 좋다.

4. Input Control 유용하다

5. 이벤트를 신경쓰지 않아도 된다.

6. Input 처리가 간편하다

 

그럼 React Hook Form을 어떻게 쓰는지 알아보겠다.

 

설치 

npm install react-hook-form

나는 요즘 진행하는 사이드 프로젝트에서 react18 rc 버전을 사용하다 보니 

--legacy-peer-deps

를 추가해서 설치했다.

 

설치했으면 일단 import 해야하지 않겠는가

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

useForm을 불러오는게 기본이다. 

 

 

register

Form에 있는 Input에 react-hook-form을 사용한다는 것을 명명해줘야 한다. 

이 부분은 useForm의 register를 사용해서 input과 연결할 수 있다.

 

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

const { register } = useForm();

<input {...register("username")} type="text" />
//이건 아래 구분과 같은 문법이다.
//<input register={"username"} type="text" />

console.log으로 확인해보면 이런 객체를 확인할 수 있다.

watch

useForm에서 watch를 쓰면 input에 입력된 값들을 확인할 수 있다.

 

const { register,watch } = useForm();

이렇게 불러와서 콘솔 확인해보면 

이렇게 input에 입력된 값을 확인할 수 있다. 

 

다시 register로 돌아와서 

input의 validation을 추가하려면

<input {...register("username", { required: true })} type="text" />

이런 식으로 추가할 수 있다. 

HTML의 required와 다른 점은 개발자 모드에서 조건을 삭제할 수 있냐 없냐 차이다.

백엔드에서 처리를 부탁해야하는 거 그럴 필요 없다고 해야 해서 

일하다 보면 개발하는 거보다 대화하는 게 더 힘들 때가 있는데 그게 더 낫다.

하지만 실질적으로 작동이 안되는데 

왜냐하면 submit 할때 e.preventDefault() 없어서 그렇다.

그래서 추가해야줘야 할게 handleSubmit이다.

 

handleSubmit

const { register, handleSubmit } = useForm();

handleSubmit parameter 2개를 받는데 한개는 onValid 하나는 onInvalid이다. 

, validation 통과할때와 실패할때의 경우에 대한 parameter다.

Valid 필수 parameter invalid 필수는 아니다.

<form onSubmit={handleSubmit(onValid, onInvalid)}>

이렇게 form의 onSubmit에 넣어서 

const onValid = () => {
        console.log("onValid execute");
    };
const onInvalid = () => {
    console.log("onInvalid execute");
};

이렇게 이벤트 처리해주면 됨.

이렇게 하면required 충족하지 않은 input으로 자동으로 커서가 간다(Amazing!!)

validation 조건만 써주면 나머지는 react hook form에서서 친절하게 컨트롤 한다.

추가로, onInvalid에서는 error 파라메터를 받아서 사용할 있다.

const onInvalid = (errors: FieldErrors) => {
    console.log(errors);
};

콘솔 찍어보면 아래처럼 에러가 잘 나온다.

required를 충족해주세요!

메시지를 넣어주고 싶은데 이렇게 넣을 수 있다.

{...register("username", { required: "Username is required" })}

콘솔로 확인해보자 

다른 Valid를 추가해보자

{...register("username", {required: "Username is required",minLength: 5,})}

콘솔로 다시 보자 

여기도 메세지를 추가해보자

 {...register("username", {
    required: "Username is required",
    minLength: {
        value: 5,
        message:"5글자 이상 써 넣어라"
    },
})}

콘솔로 보면

커스텀하는 validation은 어떻게 해야 할까?

validate를 사용해서 할 수 있다. 

{...register("email", {
    required: "Email is required",
    validate: {
        notGmail: (value) =>
            !value.includes("@gmail.com") || "Gmail 쓰지마라",
    },
})}

gmail을 거르는 validate를 만들었고 콘솔로 확인해보자

크 이쁘다

에러를 콘솔로는 보는 것을 확인했지만

인풋에 보여주고 싶다. 어떻게 해야 할까

새로운 객체를 하나 추가해야 한다.

const { register, handleSubmit,formState:{errors} } = useForm<LoginForm>();

formState를 추가했다.

이건 errors를 onInvalid의 scope를 벗어나서 사용할 수 있게 해 준다. state에 넣어준다라고 볼까나

이걸 활용해 적절한 위치에 잘 넣어주면 된다.

 

 

이제 form에 mode를 추가해보자

mode는 에러난 인풋에 빨간 표시 정상 입력 시 초록 표시되는 그런 기능이다.

const {
        register,
        handleSubmit,
        formState: { errors },
    } = useForm<LoginForm>({ mode: "onChange" });

여긴 onChage로 했지만 다양한 이벤트를 넣을 수 있다.

 

onChange로 넣어서 변경 시에 state가 반영되게 하자

formState로 errors를 잡았으니 errors에 값이 있을 때 CSS를 효과를 주면 된다. 

 

지금 하는 게 tailwind를 사용했어서 tailwind로 처리했다.

className={`${Boolean(errors.email?.message) ? "border-red-500" : ""}`}

 

소개하려고 했지만 어쩌다 보니 개발일지처럼 써진 거 같기도 하다 

아직 react hook form에는 이 포스팅에서 보다 더 많고 좋은 기능이 많다(나도 모르는)

더 관심 있고 궁금하신 분들은 아래에서 더 알아보면 좋을 거 같다.

 

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

반응형