React에서 Form다루기

니나노개발생활·2021년 7월 15일
0

💡ah-ha

목록 보기
29/51

Formik?


공식문서

  • 컴포넌트를 빌드하기 위한 React 구성 요소 및 hook들의 작은 그룹

☝🏻사용하기

  • 설치
yarn add formik
  • 임포트
import { useFormik } from 'formik';

특징

  • 단순하고 간결한 API
  • 하나의 state store 관리
  • 유효성 검사 및 오류 메시지 등을 쉽게 처리

주의

  • 단순한 Form을 처리할 때는 문제가 없지만 복잡한 Form을 다루게 되면 불필요한 리렌더링으로 퍼포먼스가 저하될 수 있다.

예시

const formik = useFormik({
  //<Form> value값
    initialValues: {
      userName: "",
      pw: "",
    },
  //submit할 때 호출되는 함수
    onSubmit: (values) => {
      // dispatch 자리
      dispatch(actionLoginForDb(values));
    },
  });

return (
	//handleSubmit : onSubmit 핸들러
	<FromBox name="registerForm" onSubmit={formik.handleSubmit}>
        <fieldset>
          {/* 닉네임 input */}
            <Input
              id="userId"
              name="userId"
              type="userId"
              //handleChange : 각 <input>, <select>, <textarea>에 전달하는 change 핸들러
              _onChange={formik.handleChange}
              //values : 폼의 현재 value
              value={formik.values.userId}
            />
            {formik.touched.userId && formik.errors.userId ? (
              <HelperMsg>{formik.errors.userId}</HelperMsg>
            ) : null}
          {/* 비밀번호 input */}
            <Input
              id="pwd"
              name="pwd"
              type="password"
              _onChange={formik.handleChange}
              value={formik.values.pwd}
              />
            {formik.touched.pwd && formik.errors.pwd ? (
              <HelperMsg>{formik.errors.pwd}</HelperMsg>
            ) : null}
          {/* 로그인 버튼 */}
          <InputBtn type="submit" value="로그인" />
        </fieldset>
      </FromBox>
  )

유효성 검사

  • 자바스크립트로 유효성 검사를 추가하려면 사용자가 직접 유효성 검사를 수행하는 함수를 정의해서 useFormik hook에게 전달해야한다.
    하지만, 이러한 방법은 코드도 길어지고 함수가 전체 폼의 값에 대해 하나의 태그에 입력된 이벤트도 호출되어 모든 유효성 검사를 거쳐 좋지 못하다.
  • 그래서 사용하는 것이 Yup을 이용한 유효성 검사

Yup

  • 사용자가 직접 유효성 검사 기능을 수행하는 함수를 정의하는 번거로움을 덜어주기 위한 라이브러리
  • Formik > validationSchema

☝🏻사용하기

  • 설치
yarn add yup
  • 임포트
import * as Yup from 'yup';

예시

const formik = useFormik({
    initialValues: {
      userId: "",
      pwd: "",
    },
	//yup 추가
    validationSchema: Yup.object({
      userId: Yup.string()
        .email("이메일 형식이 아닙니다.")
        .required("아이디를 입력해주세요!"),
      pwd: Yup.string()
        .min(4, "비밀번호는 4자리 이상이여야 합니다.")
        .matches(/[a-zA-Z]/, "패스워드에는 반드시 영문을 포함해야합니다.")
        .required("패스워드를 입력해주세요."),
    }),

    onSubmit: (values) => {
      // dispatch 자리
      dispatch(actionLoginForDb(values));
    },
  });

리팩토링

  • 시간을 절약하기 위해 useFormik은 formik.getFieldProps()라는 helper메소드를 리턴해서 입력을 더 빠르게 연결 시킨다.

예시

<Input
  id="userId"
  type="userId"
  _onChange={formik.handleChange}
  value={formik.values.userId}
   />

{formik.touched.userId && formik.errors.userId ? (
 <HelperMsg>{formik.errors.userId}</HelperMsg>
 ) : null}

React Hook Form


공식문서

☝🏻 사용하기

  • 설치
yarn add react-hook-form
  • 임포트
import { useForm } from "react-hook-form";

handleSubmit

  • form 태그 안에 a 태그나 submit 타입을 가진 버튼의 경우 이벤트 이외의 각자 고유한 기능을 가지고 있는데 우리가 선언한 이벤트 외에 페이지가 이동되거나 고유 기능이 발생하면 곤란하니 handleSubmit을 이용하여 해결할 수 있다.
import { useForm } from 'react-hook-form';
...
const { handleSubmit } = useForm();

const saveBtnClick = () => { // preventDefault() 제거
        onSaveButtonClick(inputData);
        resetForm();
    }
...
return (
    <form onSubmit={handleSubmit(saveBtnClick)}>
    ...
    </form>
)
  • 기존에는 저장 버튼을 클릭하면 바로 saveBtnClick()을 실행했지만 위 방법을 적용하면 전송하기 전 데이터 검증 및 추가적인 작업이 가능하게 되었다.

데이터 검증

  • React-Hook-Form은 데이터 검증을 보다 간단하게 하는 register을 지원한다.

예시

const { handleSubmit, register } = useForm();

//input 태그에 아래와 같이 ref = { register ( { ... } ) } 추가, name 속성이 반드시 필요
//required 는 필수 값 체크
//min,max,minLength,maxLength,pattern,validate
<div>
    제목 : <input type="text" name="boardTitle" ref={register({ required: true })} onChange={changeInput} value={inputData.boardTitle} />
</div>

err

예시
  • console.log(errors)로 확인해보면 검증에 실패한 input name 과, 어떤 검증에 실패했는지 알 수 있는 type 등을 가지고 있다.
  • 이러한 errors를 가지고 추가적인 작업을 수행!
const { handleSubmit, register, errors } = useForm();

<div>
    내용 : <input type="text" name="boardContent"  ref={register({required: true, minLength: 5})} onChange={changeInput} value={inputData.boardContent} />
   {errors.boardContent && (errors.boardContent.type == 'required' && '내용을 입력해주세요') || '최소 5글자 입력해주세요'}
                </div>

formik vs react-hook-form

  • 2021 3월 기준

참조

profile
깃헙으로 이사중..

0개의 댓글