formik + yup 사용해보기 -1

드엔트론프·2022년 11월 17일
0
post-thumbnail

이번 프로젝트에서 방을 생성하는 모달을 만들어야 했다.
방을 만들며 몇몇 부분에 대해 유효성 검사를 해야했고, form의 형태로 백엔드에 데이터를 넘겨줘야한다.

리액트에는 form을 위한 다양한 라이브러리들이 있는데, 그 중 formik이라는 친구를 사용해보기로 했다.
구글링을 해보니 여기저기 파편화된 글로 각자의 방식으로 적혀있어 처음 적응하는 데 꽤 애먹었다.
최종적으로는 어느정도 원하는 형태의 form을 구현할 수 있었는데, 결론적으로 가장 도움이 된 건 역시나 공식문서였다.

formik 튜토리얼

특히 formik은 회원가입 예제가 제일 많아서 회원가입에 쓰기 가장 쉬울 것 같다.
위 링크의 튜토리얼을 정말 차근차근 살펴본다면, 마지막엔 기본적인 유효성검증과 폼 데이터를 컴포넌트 형태로 구분하여 사용할 수 있다.

굳이? 싶다면, 사실 초반만 잘 익혀도 formik을 사용하는 데 무리가 없다.
먼저 예시로 작성할 코드는 튜토리얼에 있는 코드 그대로이며, yup으로 확인하는 유효성검증은 다음편에 차차 작성해보려한다.

시작하기

라이브러리를 설치해준다.
yarn add formik

기본 사용

input값은 email 하나만 받는 형태이다.
설정해둔 initialValues가 input 작성 후 제출하게 되면 알럿창에 input 값이 뜬다.

import React from 'react';
 import { useFormik } from 'formik';
 
 const SignupForm = () => {
   const formik = useFormik({
     initialValues: {
       email: '',
     },
     onSubmit: values => {
       alert(JSON.stringify(values, null, 2));
     },
   });
   return (
     <form onSubmit={formik.handleSubmit}>
       <label htmlFor="email">Email Address</label>
       <input
         id="email"
         name="email"
         type="email"
         onChange={formik.handleChange}
         value={formik.values.email}
       />
 
       <button type="submit">Submit</button>
     </form>
   );
 };

initialValues와 onSubmit 함수를 useFormik 훅으로 보내주면,
그 훅은 우리가 formik이라고 부르는 변수에 폼 상태와 헬퍼 메서드를 반환해준다.

지금 우리가 봐야할 헬퍼 메서드는 3개다
handleSubmit: 제출하는 친구
handleChange: input, select, textarea에 사용.
values: 현재 폼의 값

가장 기본의 형태를 보자면 어떠한 유효성 검증도 없고,
기존 쌩 form을 작성하는 것과 크게 달라보이지 않는다.
그치만 onChange를 봐보자.
항상 변하는 input값을 확인하고 그 값을 보내기 위해서 onChangeHandler를 만들고 위에서 e.target.value를 하는 귀찮은 일을 하지 않는 걸 볼 수 있다..!
이게 얼마나 편한지 하나의 input으로는 감이 안올 수 있다. 성, 이름까지 3개의 input을 받는 form을 살펴보자.

3개의 input을 받는 형태

 import React from 'react';
 import { useFormik } from 'formik';
 
 const SignupForm = () => {

   const formik = useFormik({
     initialValues: {
       firstName: '',
       lastName: '',
       email: '',
     },
     onSubmit: values => {
       alert(JSON.stringify(values, null, 2));
     },
   });
   return (
     <form onSubmit={formik.handleSubmit}>
       <label htmlFor="firstName">First Name</label>
       <input
         id="firstName"
         name="firstName"
         type="text"
         onChange={formik.handleChange}
         value={formik.values.firstName}
       />
 
       <label htmlFor="lastName">Last Name</label>
       <input
         id="lastName"
         name="lastName"
         type="text"
         onChange={formik.handleChange}
         value={formik.values.lastName}
       />
 
       <label htmlFor="email">Email Address</label>
       <input
         id="email"
         name="email"
         type="email"
         onChange={formik.handleChange}
         value={formik.values.email}
       />
 
       <button type="submit">Submit</button>
     </form>
   );
 };

initialValue에는 form에 들어가는 모든 값을 기본적으로 설정해주어야 한다. 안그러면 에러난다.

중복되는 형태가 눈에 띄지만, onChange 와 value를 거의 똑같은 형태로 적어도 된다는 점이 매우 편하다. 👀
이게 어떻게 가능할까? 문서에는 다음과 같이 적혀있다.

  1. 각각의 HTML input에 똑같은 handleChange 핸들러 함수를 재사용한다.
  2. initialValues에서 정의한 속성과 일치하는 id 및 name HTML 속성을 전달한다.
  3. 동일한 이름을 사용해서 필드에 접근한다. (email -> formik.values.email)

이러한 형태로 formik이 작동한다.

공식문서에도 내가 귀찮아하는 handleChange에 대해 언급해놨다 ㅋㅋ

각각의 handleChange에 대응하는 형태의 handleChange 함수

 const [values, setValues] = React.useState({});
 
 const handleChange = event => {
   setValues(prevValues => ({
     ...prevValues,
     // we use the name to tell Formik which key of `values` to update
     [event.target.name]: event.target.value
   });
 }

나는 아직도 이 형태가 헷갈린다..

다음편에는 유효성검증까지 하는 형태를 작성해보려한다 !

profile
왜? 를 깊게 고민하고 해결하는 사람이 되고 싶은 개발자

0개의 댓글