Web-Frontend/React.js

[React.js] React Hook Form

서노리 2023. 4. 5. 04:02
반응형

React Hook Form

React Hook Form 이란 폼의 유효성 검사를 쉽고 간단하게 만들 수 있는 리액트 라이브러리이다.

 

일반적인 폼 생성 방법

import { useState } from "react";

function ToDoList() {
  const [todo, setTodo] = useState("");
  //에러 만들기
  const [toDoError, setToDoError] = useState("");

  //onChange 이벤트 
  const onChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setTodo(value);
  };
  //onSubmit 이벤트
  const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    //글자수가 10자 미만일 때 에러가 발생
    if(todo.length < 10) {
        return setToDoError("글자 수가 부족함")
    }
    setToDoError("");
    console.log(todo);
  };
  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;

위 예제처럼 리액트에서 일반 form 태그를 이용하면 각 input 값에 대한 useState와 onChange를 작성하고, submit에서는 여러 검증 코드를 넣어야한다. 또한 여러 에러에 대한 useState도 관리해야하는 등 매우 복잡한 절차를 걸쳐야한다. React Hook Form은 이러한 문제를 해결해준다.

 

React Hook Form 설치하기

npm i react-hook-form

 

React Hook Form 사용하기 - useForm

Register

React Hook Form의 useForm을 사용하여 여러 개의 state를 두는 방법을 대체할 수 있다.

register에는 name, onBlur, onChange, ref를 갖고 있어 스프레드 연산자를 이용하여 register를 넣어주면 input에 해당 값들이 prop으로 들어가게 된다. 따라서 여러 개의 input을 사용할 때 각각의 state와 onChange를 만들어줄 필요가 없이 {...register("이름")}만 써주면 된다.

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

export default function Forms() {
	const { register } = useForm();
  return (
    <form>
      <input
    	{...register("email")}
        type="email"
        placeholder="Email"
        required
      />
      <input
	{...register("password")}
        type="password"
        placeholder="Password"
        required
      />
      <input type="submit" value="Create Account" />
    </form>
  );
}

※ register에 들어간 값 확인하기 - watch()

const { watch } = useForm();
console.log(watch());

※ input의 기본값 설정하기 - defaultValues

  const {
    register,
    watch,
    handleSubmit,
    formState: { errors },
    setError,
  } = useForm<IForm>({
    //   input의 기본값 설정
    defaultValues: {
      email: "@naver.com",
    },
  });

유효성 검사

register는 폼의 유효성 검사를 쉽게 해준다.

 

※ 지원되는 유효성 검사

  • required
  • min
  • max
  • minLength
  • maxLength
  • pattern
  • validate : 임의의 사용자 정의 함수로 유효성 검사를 하고싶은 경우 사용
<input
  {...register("email", {
    //입력 필수
    required: true,
    pattern: {
      //pattern은 정규식을 이용. @naver.com 형식만 가능하도록 해준다.
      value: /^[A-Za-z0-9._%+-]+@naver.com$/,
      message: "네이버 이메일만 가능",
    },
  })}
  placeholder="Email"
/>

 

handleSubmit

handleSubmit은 form의 submit을 관리하는 메소드로, 기본적으로 event.preventDefault() 기능을 가지면서 onValid와 onInvalid 두 개의 함수를 인자로 받는다. register에 입력되어 있는 규칙에 따라 onValid는 폼이 유효할 때 동작하고, onInvalid는 폼이 유효하지 않을 때 동작한다.

interface LoginForm {
  password: string;
  email: string;
}

export default function Forms() {
  const { register, handleSubmit, formState: { errors } } = useForm<LoginForm>();
  const onValid = (data: LoginForm) => {
    console.log("im valid");
  };
  const onInvalid = (errors: FieldErrors) => {
    console.log("im invalid");
  };
  return (
    <form onSubmit={handleSubmit(onValid, onInvalid)}>
  		{...children}
		{errors.email?.message}
    </form>
  );

유효하지 않은 input 값으로 인해 발생한 에러를 화면에 표시할 때는 formState: { errors }를 이용한다.

 

setError

formState: { errors }가 input의 오류를 저장한다면 setError는 임의로 특정한 에러를 발생시키는 메소드이다.

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

  const onVaild = (data: IForm) => {
    if(data.password !== data.password1) {
    // 만일 password와 password1이 일치하지 않는 경우 발생하는 에러 설정
        return setError("password1", {message: "비번이 일치하지 않습니다."},{ shouldFocus: true })
    }
  };

 

setValue

setValue는 register의 어떠한 상태 값을 임의의 값으로 변경시키는 메소드이다.

setValue("필드 명", "값");

const { register, handleSubmit, setValue } = useForm<IForm>();
  const onSubmit = (data: IForm) => {
    console.log("add to do", data.toDo);
    setValue("toDo", "");
  };

 

반응형

'Web-Frontend > React.js' 카테고리의 다른 글

[React.js] React에서 Font Awesome 사용하기  (0) 2023.06.03
[React.js] Recoil - Selector  (0) 2023.04.18
[React.js] Recoil - atom  (0) 2023.03.28
[React.js] React Query  (0) 2023.03.22
[React.js] React에 Typescript 적용하기  (0) 2023.03.14