useForm 사용하여 로그인 & 회원가입 구현 - 2. 회원가입

이전 포스트에서 useForm을 활용해서 로그인을 구현하였다.

 

useForm 사용하여 로그인 & 회원가입 구현 - 1.로그인

기존 프로젝트의 회원가입 & 로그인은 아래와 같이 global state로 유저 email, 비밀번호, 이름 등의 정보를 관리하여 한번에 signup 혹은 login API를 호출할 때, body에 json 형태로 담아 호출하는 방식으로

eight20.tistory.com

회원 가입 페이지의 경우, 한 페이지에 모든 유저 정보를 기입하게 Form을 구성하고, 회원 가입 클릭 시, 유저가 기입한 정보를 json 형식으로 전송하는 방식과, 여러 페이지에 걸쳐서 email, password 따로, 유저 이름, 휴대폰 번호등의 세부 정보를 따로 받는 방식의 두 가지 형태로 구분된다. 

한 페이지에 모든 유저 정보를 입력받아 Form을 구성하는 경우만 이 포스트에서 다루겠다.

아래와 같이 SignupPage.tsx를 생성한 후, useForm을 사용하여 구성한다.

interface FormValues {
    email: string;
    password: string;
    confirmPassword: string;
    username: string;
}

export const SignupPage = () => {
    '''''''''' 생략 ''''''''''
    const {
     watch,
     register,
     setError,
     handleSubmit,
     formState: { errors },
    } = useForm<FormValues>();
    
    return (
    	<div>
          <H1>회원가입</H1>
          <form>
            <TextField 
               type="이메일" 
               label="이메일" 
               placeholder="이메일을 입력해주세요." 
               helper={errors.email?.message}
               />
            <TextField 
            type="비밀번호"
            label="비밀번호"
            placeholder="비밀번호를 입력해주세요."
            helper={errors.password?.message}
            />
            ........ 생략 ........
          </form>
        </div>
    )
}

로그인에서 했던 구현 방식과 동일하게 FormValues를 interface타입으로 선언한 후, 회원 가입에 필요한 정보와 그에 맞는 타입을 지정한다. <TextField> 태그를 통해 필요한 정보 만큼 Text창을 구성한다. 

<form> 태그의 onSubmit 옵션을 사용하여 회원가입을 하는 API에 handleSubmit 함수를 사용하여 form 안에 저장된 data를 API 요청 시 body 안에 포함시킨다.

<form 
  onSubmit={handleSubmit((data) => {
      if (data.password !== data.confirmPassword) {
            setError('confirmPassword', {
              message: '비밀번호가 다릅니다. 다시 확인해주세요.',
            });
          } else {
            api
              .post('/users/valid-email', { email: data.email })
              .then(() =>
                history.push('/signup', {
                  data,
                })
              )
              .catch(
                (e) =>
                  e.response.status === 409 &&
                  setError('email', {
                    message: '중복된 이메일이 이미 존재합니다.',
                  })
              );
          }
        })}