넷째주 #18 React Js - React-hook-form

김선은·2023년 6월 6일

react-hook-form

일반적인 react의 form! infut과 onChange

  • input마다 setState, onChange Fn 만들어야 함
function ToDoList() {
  const [toDo, setToDo] = useState("");
  const onChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setToDo(value);
  };
  const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    console.log(toDo);
  };
  
  return (
    <div>
      <form onSubmit={onSubmit}>
        <input onChange={onChange} value={toDo} placeholder="Write a to do" />
        <button>Add</button>
      </form>
    </div>
  );
}

하지만 react-hook-form 을 쓴다면?

  • form validation 많더라도 유효성 검사가 더 편리함
  • register 함수가 다 함. setState, onChnage 이벤트 핸들러 필요 없다.
  • form의 onSubmit은 handleSubmit이 대신 처리해줄거라고~!
  • handleSubmit : validation, preventDefault, 등등 해줌
    • handleSubmit은 2개 인자를 가질 수 있고 onVaild는 필수
    • onVaild 데이터 유효할 때 호출되는 함수. validation 끝나면!
    • onInvalid 데이터 유효하지 않을 때 호출. 필수 아님
    • formState validation의 에러를 객체로 확인할 수 있음
  • setValue : 제출 후 input 값 비워줄 수 있음
// npm i react-hook-form
import { useForm } from "react-hook-form"

function List() {
 const { register, watch, handleSubmit, formState, setValue } = useForm();
 console.log(watch()); // form 모든 값을 주시할 수 있음
 const onVaild = (data) => {
 console.log(data); // 제출, input값 콘솔로 볼 수 있음
 setValue("input name", "")
 } 
 return (
   <form onSubmit={handleSubmit()}>
     <input
      {...register("email")} placeholder="Email" />
   </form> 
   ) 
}

{...register("email", {required:true, minLength: 10})}
//register 안에 required 넣을 수 있음. validation !

{...register("password", {required:"패스워드 입력하세요"
 , minLength: 10})}

정규식으로 패턴 검사하기

  • required 안에 pattern 사용
<input 
	{...register("email", {required:true, 
	pattern: /^[A-Za-z0-9._%+-]+@naver.com$ })} />

// 패턴 안에도 메세지 가능
<input
	{...register("email", {required:"이메일을 입력하세요", 
	pattern: {
    value:/^[A-Za-z0-9._%+-]+@naver.com$,
    message: "Only naver.com emails allowed"
 	}
})} />
//required에 message 입력하면 에러 시 메세지 보여 줄 수 있음.
<sapn> {formState.errors?email?.meassage} </span>
// 에러의 타입이 required인지 pattern인지는 알아서 해줌

ts에게 form 알려주기

  • IForm 인터페이스에 입력 받아야 하는 항목들 넣기
  • useForm 과 Onvaild 에 인터페이스 적용

interface IForm {
email: string;
password: string;
passwordConfirm: string;
extraError?: string;
}

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

const onVaild = (data: IForm) => console.log(data)

defaultValues: useForm 에 기본값 주기

  • defaultValues

const { register, watch, handleSubmit, formState } = useForm<IForm>({
  defaultValues: {
  	email: "@naver.com"
  }
});

formState: 에러 발생시키기

  • password와 password 확인이 같지 않을 경우 에러 발생시키기 setError
const { register, handleSubmit, formState:{errors}, setError } = useForm<IForm>();

const onVaild = (data: IForm) => {
  if(data.password !== data.passwordConfirm) {
  	setError("passwordConfirm", {message:"비번이 다릅니다"},
    {shouldFocus: true}) // shouldFocus 에러난 곳에 커서 옮겨준다.
  }
  setError("extraError", {message: "Server Offline"})
  // 특정 항목에 해당하는 에러가 아닌, 전체 form에 해당하는 에러
}

return (
  ...
<span>{errors?.extraError?.message}</span>
  // ? 를 붙이면 그 항목이 undefined라면 뒤에를 실행하지 않는다.
)
  • 닉네임에서 특정 단어를 허용하지 않게하기
  • validate 는 함수를 값으로 가짐. 인자로 현재 쓰여지는 값을 받음.
  • validate는 하나의 함수 또는 여러 함수가 있는 객체가 될 수 있음
  • async로 비동기로 만들어서 서버에 확인하고 응답을 받을 수 있음(중복 닉네임)
<input>
  {...register("nickName", 
  { required: true, validate: (value) => 
   value.includes("fuck") ? "허용되지 않습니다" : true,
  })}
</input>

<input>
  {...register("nickName", 
  { required: true, validate: {
    noFuck: (value) => value.includes("fuck") ? "허용되지 않습니다" : true,
    noSibal: (value) => ...중략
  },
  })}
</input>

validation 정리

  1. register 내부의 requiredmessage 적기
...register("email" , {required: "필수 입력입니다"})
  1. register 내부에 validate 쓰기
...register("nickName", { required: true, validate: ... }
  1. register 내부에 옵션 사용하기 ex) minLength
...register("nickName", { required: true, minLength: 2 }

// 객체로 value와 message 사용 가능
minLength: {
	value: 2,
    message: "너무 짧습니다"
}
profile
기록은 기억이 된다

0개의 댓글