코드 캠프 24일차) 리액트 훅 폼

민겸·2022년 10월 25일
0

코드캠프_FE09

목록 보기
24/28
  1. React-Hook-Form
  2. Yup
  3. Common-Component

type 과 interface 차이

  • type은 같은 이름으로 작성 불가, interface는 가능(선언 병합)

긴 이름의 타입은 코드 흐름에 필수적이지 않다면 따로 빼놓자..!

1. React-Hook-Form

input태그들이 모여있는 입력 양식에는 form 태그를 사용해서 묶어주면 입력 양식의 결과를 받기가 수월해지고, 추가적인 유효성 검사를 쉽게 할 수 있다는 장점이 있다.

리액트에서도 form태그를 위한 훅이 존재한다. 그것이 바로 리액트 훅 폼이다.

대략적인 사용법은 아래와 같다.

우선, 리액트 훅 폼 라이브러리를 설치한다.

npm install react-hook-form
yarn add react-hook-form

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

interface IFormData {
  writer: string;
  title: string;
  contents: string;
}

const { register, handleSubmit, watch, formState: { errors } } = useForm<IFormData>();
위와 같이 선언을 해서 쓸 수 있다.

const onSubmitFn = (data: IFormData) => console.log(data);

const onClickSpecialButton = () => console.log("난 눌러도 form 제출 안 됨!");

return (
  // useForm에서 handleSubmit을 꺼내서 submit함수를 감싸주면,
  // register에 저장된 input의 데이터들이 onSubmitFn에 저장된다.
  // onSubmitFn에 저장된 데이터는 인자에서 꺼내서 사용할 수 있다. (4 번째 줄)
  <form onSubmit={handleSubmit(onSubmitFn)}>
    // register 안에는 onChange, onInput, .. 등등이 들어있고,
    // 인자로 해당 input의 주제(이름)를 정해주면 된다.
    <input type="text" {...register("title")} placeholder="제목" />
    <input type="text" {...register("content")} placeholder="내용" />
    <button>등록하기</button>
    // form 안에서 따로 특정 기능을 가진 버튼을 만드려면 type="button"을 넣어주자.
    <button type="button" onClick={onClickSpecialButton}>다른 기능 버튼</button>
  </form>
 );

제어 컴포넌트와 비제어 컴포넌트

제어 컴포넌트 방식은 컴포넌트에 onChange와 같은 핸들러를 달아서 입력할 때 마다 값을 실시간으로 읽어 state로 저장하는 방식이다.
제어 컴포넌트는 실시간 동기화가 되면서 정확성이 높다는 장점이 있지만, 입력 데이터가 많아질 수록 리렌더링도 발생함에 따라 성능이 떨어진다는 단점이 있다.

비제어 컴포넌트 방식은 컴포넌트의 값을 입력할 때 마다 읽는 것이 아닌 useRef 와 같은 것을 이용해서 가장 최근 값만을 '조회'하는 방식이다.
비제어 컴포넌트는 실시간 동기화가 불가능하고 정확성이 떨어지지만, 입력 데이터가 아무리 많아도 현재값만을 원할 때 한 번 '조회'하기 때문에 리렌더링이 일어나지 않아서 입력 데이터의 양에 따른 성능 저하가 없다는 장점이 있다.

리액트 훅 폼은 비제어 컴포넌트 방식이다.

2. Yup

Yup은 실시간 데이터 파싱과 유효성 검사를 위한 schema builder이다.

schema builder란?

스키마 빌더는 데이터 모델을 시각화하고 편집할 수 있는 도구를 뜻한다.

Yup의 사용법

우선, yup을 사용하기 전에 필요한 라이브러리들을 설치하자.
나는 리액트 훅 폼과 연결하여 쓰기 위해 yup과 함께 hookform/resolver를 같이 설치했다.

yarn add @hookform/resolvers yup

import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
// 가장 먼저 import를 해준다.
import {useForm} from "react-hook-form";

const mySchema = yup.object({
  // yup 스키마 작성하는 방법! 타입 검사를 해준 뒤, 필수값인지 아닌지, 필수값일 때 빈값이 오면 띄울 에러메세지까지 한 방에!!
  writer: yup.string().required("작성자를 입력해주세요."),
  title: yup.string().required("제목을 입력해주세요."),
  contents: yup.string().required("내용을 입력해주세요."),
  password: yup
    .string()
    .min(4, "비밀번호는 4자리 이상이어야 합니다.")
    .max(15, "비밀번호는 15자리 이하이어야 합니다.")
    .required("비밀번호를 입력해주세요."),

  // email: yup
  //   .string()
  //   .email("이메일 형식에 적합하지 않습니다.")
  //   .required("이메일을 입력해주세요."),
  // phone: yup
  //   .string()
  //   .matches(/^\d{3}-d{3,4}-d{4}$/, "전화번호 형식에 적합하지 않습니다.")
  //   .required("전화번호를 입력해주세요."),
});

interface IFormData {
  writer: string;
  title: string;
  contents: string;
}

const { register, handleSubmit, watch, formState: { errors } } = 
      // useForm과 yup을 연결하기 위해서 useForm()의 인자로 resolver를 넣고 
      // resolver 키의 값으로 yupResolver를 넣고
      // yupResolver의 인자로 내가 작성한 커스텀 스키마를 넣어준다... 인자의 키의 인자의..😇
      useForm<IFormData>({resolver: yupResolver(mySchema), mode: "onChange"});
	  // useForm()의 인자로 resolver 말고도 mode 키를 넣어서 
	  // 비제어 -> 제어 컴포넌트로 전환이 가능 -> 실시간으로 유효성 검사 가능

const onSubmitFn = (data: IFormData) => console.log(data);

const onClickSpecialButton = () => console.log("난 눌러도 form 제출 안 됨!");

return (
  <form onSubmit={handleSubmit(onSubmitFn)}>
    <input type="text" {...register("title")} placeholder="제목" />
{/* useForm() 훅의 폼의 상태를 보여주는 formState에서 error를 가져와 유효성 검사를 통과하지 못하면 에러를 렌더링 해주기위해 div 배치  */}
    <div>{errors.title?.message}</div>
    <input type="text" {...register("content")} placeholder="내용" />
    <div>{errors.contents?.message}</div>
    <button>등록하기</button>
    <button type="button" onClick={onClickSpecialButton}>다른 기능 버튼</button>
  </form>
 );

3. Common-Component

공통 컴포넌트와 같이 나 뿐만 아니라 같이 일하는 사람이 쓸 수도 있는 데이터나 자료는 한 눈에 알아볼 수 있게 이름을 잘 지어놓는 것도 좋지만, 갯수가 많아진다면 결국 난잡해지기 때문에 번호를 붙여놓고 해당 번호가 어떤 파일인지 정리해놓는 가이드 문서를 작성해놓는 것이 더 좋을 수도 있다. 문서 작성은 예로 들면 storybook이 있다.

profile
기술부채상환중...

0개의 댓글