#2.항해 sw camp 로그인 회원가입 기능 제작

김재우·2023년 3월 16일
0

react-hook-form

목록 보기
1/1

개발기간이 2주뿐이여서 기능 구현에만 집중한 나머지 블로그 정리할 여건이 되지 않았다.
mvp 기능까지 구현을 마친 상태에서 밀린 포스트를 작성하려고 한다.
내가 프로젝트에서 맡은 구현은 로그인과 회원가입 기능이고 내가 이 기능을 맡은 이유는
평소 경험하지 못했던 파트이기도 하고 한번쯤 유효성 검사 같은걸 제대로 할 줄 알아야 한다고 생각이 들었기 때문이다.

우리의 프로젝트에 회원가입 단계는 이렇게 진행된다.
1.먼저 이메일을 입력하고 회원가입 버튼을 누른다.
2.해당 이메일 주소로 백엔드에서 인증메일을 보내준다.
3.이름과 비밀번호를 입력하고 서비스 약관에 동의하여 회원가입을 마친다.

프로젝트의 wire frame

사실 일반적인 회원가입이면 form 안에 여러가지 회원정보들을 기입하고 한번에 회원가입을 마쳐야 하는데 pm분들이 이렇게 기획을 해주셨고 회원가입에서 최대한 시간을 뺏지 않고 고객들에게 좋은 ux (user experience) 를 제공할 수 있다는 생각이 들어서 동의했다.

로그인과 회원가입에 대한 파트가 생각보다 너무 쉽게 구현이 되어서 나는 좀 더 심화적으로 어떤 부분을 더 공부할 수 있는지 찾아 보았다. 그렇게 구글링을 한 결과.
로그인과 회원가입에서 뗄수없는 react-hook-form, formlik , yup 이라는것에 대해서 알게 되었다.

1.먼저 react-hook-form 이란?

React Hook Form은 고유한 규칙으로 입력을 검증할 수 있는 기본 양식 유효성 검사를 지원합니다. -react hook form 공식 홈페이지 발췌-

추가적으로 구글에 검색결과를 참고하면 !!
React에서 form의 validation을 빠르고 쉽게 도와주는 라이브러리이다. 전체 폼이 리랜더링 되지 않으면서도 각각의 입력값 변화를 관찰할 수 있기에 성능도 빠르고 의존성 없이 쉽게 사용 가능하다.

내가 진행하는 프로젝트도 react 프로젝트이기 때문에 그리고 무엇보다 react 는 state 값이 바뀌면 렌더링 되는 특징을 갖고있고 ref 로 관리해주는 state 는 리 렌더링 되지 않지만 일일히 모든 input에다가 ref 를 연결하기엔 너무나도 귀찮은 작업이다. 그런데 react-hook-form 라이브러리를 사용하면 전체 폼이 리 렌더링 되지 않고 각각의 입력값들의 변화를 관찰 할 수 있기에 도입하게 되었다.

2. yup이란?

Yup 이란 Yup은 모델의 스키마를 정의할 수 있도록 하며, 유효 값 검증(validation), 형 변환(parsing), 원하는 값으로 조작(transformation)등의 기능을 제공하는 라이브러리 입니다. 이를 통해 더욱 안정성 있는 어플리케이션의 설계와 구현이 가능합니다. -구글링 결과-

좋은점은 둘다 Typescript 를 지원해준다는 장점이 있다.

3.라이브러리 설치방법

$ yarn add react-hook-form
$ yarn add yup
$ yarn add @hookform/resolvers yup ## yup과 react-hook-form 을 연결 시켜주는 라이브러리

4. react-hook-form 과 yup 사용방법

1-1 유효성 검사 모듈인 스키마를 만든다.

const schema = yup.object().shape({
    name: yup
      .string() //문자열 제일먼저 체크
      .required('이름을 입력해주세요.') //다음 빈칸인지 체크
      .matches(/^[가-힣]{2,20}$/, '2~20자로 입력해주세요.'), //다음 정규식 체크
    password: yup
      .string() //문자열 체크
      .required('비밀번호를 입력해주세요') // 빈칸인지 체크
      .matches(
        /(?=.*\d{1,50})(?=.*[~`!@#$%\^&*()-+=]{1,50})(?=.*[a-zA-Z]{2,50}).{8,30}$/,
        '비밀번호를 8~30자로 영문 대소문자, 숫자, 특수문자를 조합해서 사용하세요.',
      ) // 정규식 체크 후 
      .min(8, '비밀번호는 최소 8글자 이상입니다.') //비밀번호 최소 자리 체크
      .max(30, '비밀번호는 최대 30글자 이상입니다.'), // 비밀번호 최대 자리 체크
  });

1-2 react hook form 을 만든다.

 //react-hook-form
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm<FormValue>({
    resolver: yupResolver(schema),
    mode: 'onChange',
  });

1-3 form 과 input 에 도입시킨다.

<InfoBox onSubmit={handleSubmit(signupHandler)}> 
        <Text>마지막으로,이름과 비밀번호를 입력해주세요.</Text>
        <Name
		
          className={errors.name?.message && 'error'}
			//react-hook-form 도입 부분 name 유효성 검사
          {...register('name', { required: true })}
          id="name"
          name="name"
          value={name}
          onChange={onChange}
          placeholder="이름"
        />
            //이름 유효성 검사 에러 메시지 부분
        <Errormessage>{errors.name?.message}</Errormessage>
			// 패스워드 유효성 검사 부분
        <Password
          className={errors.password?.message && 'error'}
          {...register('password', { required: true })}
          id="password"
          name="password"
          value={password}
          onChange={onChange}
          type="password"
          placeholder="비밀번호"
        />
            //패스워드 유효성 검사 에러 메시지 부분
        <Errormessage>{errors.password?.message}</Errormessage>

       (...)

        <ManageBtn type="submit">관리어쩔 시작하기</ManageBtn>
      </InfoBox>

1-4 전체코드

import React, { useState } from 'react';
import { useRecoilState } from 'recoil';
import styled from 'styled-components';
import { UserApi } from '../apis/axiosInstance';
import enter from '../assets/enterinfo.svg';
import { useUserState } from '../recoil/userList';
import useInputs from './../hooks/useInput';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
import { SubmitHandler, useForm } from 'react-hook-form';
import { FormValue } from './Landing';
import { User } from './../recoil/userList';
import { useNavigate } from 'react-router-dom';

const EnterInfo = () => {
  const [{ name, password }, onChange, Reset] = useInputs({
    name: '',
    password: '',
  });
  const navigate = useNavigate();

  const [info, setInfo] = useRecoilState(useUserState);
  const [agreePi, setAgreePi] = useState<boolean>(false);
  //yup schema
  
  //유효성 검사를 한번에 할 수 있는 스키마를 만들어 간편하게 관리할 수 있음.!
  
  const schema = yup.object().shape({
    name: yup
      .string() //문자열 제일먼저 체크

      .required('이름을 입력해주세요.') //다음 빈칸인지 체크
      .matches(/^[가-힣]{2,20}$/, '2~20자로 입력해주세요.'), //다음 정규식 체크
    password: yup
      .string() //문자열 체크

      .required('비밀번호를 입력해주세요') // 빈칸인지 체크
      .matches(
        /(?=.*\d{1,50})(?=.*[~`!@#$%\^&*()-+=]{1,50})(?=.*[a-zA-Z]{2,50}).{8,30}$/,
        '비밀번호를 8~30자로 영문 대소문자, 숫자, 특수문자를 조합해서 사용하세요.',
      ) // 정규식 체크 후 
      .min(8, '비밀번호는 최소 8글자 이상입니다.') //비밀번호 최소 자리 체크
      .max(30, '비밀번호는 최대 30글자 이상입니다.'), // 비밀번호 최대 자리 체크
  });
  //react-hook-form
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm<FormValue>({
    resolver: yupResolver(schema),
    mode: 'onChange',
  });
  

  const signupHandler: SubmitHandler<FormValue> = () => {
    const signup = async () => {
      try {
        await UserApi.signup(info, password, name, agreePi);
        navigate('/');
      } catch (error: any) {
        window.alert(error?.response?.data.error);
      }
    };
    signup();
  };

  return (
   (...)
    //form 시작 부분에 onSubmit 함수를 만들어 앞에 handleSubmit을 붙여주고 그 다음엔 
    //해당 데이터를 보내는 비동기 함수를 넣어줍니다.
    //handleSubmit = react-hook-form 에서 제공하는 함수
    //signupHandler = 백엔드에게 데이터 보내는 비동기 함수
      <InfoBox onSubmit={handleSubmit(signupHandler)}> 
        <Text>마지막으로,이름과 비밀번호를 입력해주세요.</Text>
        <Name
		
          className={errors.name?.message && 'error'}
			//react-hook-form 도입 부분 name 유효성 검사
          {...register('name', { required: true })}
          id="name"
          name="name"
          value={name}
          onChange={onChange}
          placeholder="이름"
        />
            //이름 유효성 검사 에러 메시지 부분
        <Errormessage>{errors.name?.message}</Errormessage>
			// 패스워드 유효성 검사 부분
        <Password
          className={errors.password?.message && 'error'}
          {...register('password', { required: true })}
          id="password"
          name="password"
          value={password}
          onChange={onChange}
          type="password"
          placeholder="비밀번호"
        />
            //패스워드 유효성 검사 에러 메시지 부분
        <Errormessage>{errors.password?.message}</Errormessage>

       (...)

        <ManageBtn type="submit">관리어쩔 시작하기</ManageBtn>
      </InfoBox>
  

react-hook-form 과 yup모듈을 이용하여 유효성 검사를 하니 좀 더 에러 핸들링을 잘할 수 있었고 유효성 검사에 최적화 되어있는 라이브러리라는것이 체감이 된다. 좋은 라이브러리를 알게되서 기분이 좋다..ㅎㅎ

profile
프론트엔드 꾸준개발자입니다.

0개의 댓글