로그인 기능을 간편하게, React-hook-form

강민혁·2023년 5월 31일
0

프로젝트

목록 보기
6/7
post-thumbnail

이전 포스팅에서는 python으로 백엔드를 구축했는데요 이번 포스팅에서는 본격적으로 프론트엔드를 짜보겠습니다.
제가 생각한 프론트엔드 흐름은 다음과 같습니다.

메인페이지 > 로그인 > 예약 > 조회 및 취소

간단한 페이지이지만 로그인이 필수로 필요합니다.

로그인이 필수로 필요한 이유?

개발하고자 하는 프로젝트가 SRT에 기반하여 만들어지기 때문에
SRT모듈에 접근하여 예약 및 취소기능을 실행하기 위해서는
반드시 로그인 이라는 기능이 필요합니다.

설명이 되었다면 본격적으로 로그인을 구현해보도록 하겠습니다.

React-hook-form?

워낙 많이쓰이고 유명한 라이브러리 입니다.
자체적으로 만들어서 로그인 창을 구현할 수도 있겠지만
React-hook-form에서는 라이브러리에서 유효성 검사를 지원하기 때문에
빠르게 구현하기 좋을것 같아 사용하기로 했습니다.

유효성검사?

아직 프론트엔드를 접하신지 얼마안되시다면 생소할 수 있습니다.

유효성 검사

사용자로부터 입력받은 데이터의 유효성을 확인하는 과정입니다. 폼에서 사용자로부터 입력된 데이터는 종종 특정한 규칙이나 조건을 충족해야 합니다. 예를 들어, 이메일 주소는 유효한 형식이어야 하고, 비밀번호는 특정한 길이나 문자 조합을 가져야 합니다.

본론으로 돌아가서 React-hook-form을 본격적으로 구현해보겠습니다.

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

function MyForm() {
  const { register, handleSubmit, errors } = useForm();

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        type="email"
        name="email"
        ref={register({
          required: '이메일 주소를 입력해주세요.',
          pattern: {
            value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
            message: '유효한 이메일 주소를 입력해주세요.',
          },
        })}
      />
      {errors.email && <p>{errors.email.message}</p>}
      
      <input type="submit" value="제출" />
    </form>
  );
}

useForm()

useForm()이란 React-hook-form에서 지원하는 Hooks입니다.

const { register, handleSubmit, errors } = useForm();

useForm 훅에서 register, handelSubmit, errors를 가져옵니다.

register

유효성검사를 지원하는 함수입니다.

<input
        type="email"
        name="email"
        ref={register({
          required: '이메일 주소를 입력해주세요.',
          pattern: {
            value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
            message: '유효한 이메일 주소를 입력해주세요.',
          },
        })}
      />

이 코드를 보시면 register를 사용합니다.
register안에 required, pattern, value, message가 존재합니다.
required : 필수로 입력해야 하는 조건입니다.
pattern : 유효성검사를 하기위한 일련의 조건을 거는 객체입니다.
value : 일련의 조건을 거는 값입니다. 위 코드는 이메일에 대한 정규식을 나타내고 있습니다.

message : 조건을 통과하지 못할 시 나타내는 문구입니다.

handelSubmit

폼을 제출했을때 콜백함수를 인자로 받는 함수입니다.

errors

유효성검사 통과실패시 이에 대한 결과를 제공하는 객체입니다.

저는 이 3가지로 로그인을 구현했습니다.

UI는 MUI를 적용해 깔끔하게 만들었습니다.
register를 이용해 유효성 검사를 하게 만들었으며,
유효성검사 실패시 error메세지를 반환하게 만들었습니다.

마지막으로 작성한 코드 올려드리고 이번 포스팅 마치도록 하겠습니다.

import Header from '../components/Header';
import React, { useState, useEffect } from 'react';
import '../css/login.scss';
import { useForm } from "react-hook-form";
import { Button, TextField } from '@mui/material';
import axios from 'axios';
import { Navigate } from 'react-router-dom';

export default function Login() {
    const {
        register,
        handleSubmit,
        formState: { isSubmitting, isDirty, errors },
    } = useForm();
    return (
        <div>
            <Header />
            <div className='login-card card'>
                <div className='login-banner'>
                    <h1>SRT 자동예약 서비스</h1>
                    <span>SRT Reservation Login</span>
                    <span>본 서비스의 상업적 사용을 금합니다.</span>
                </div>
                <h2>Login</h2>
                <form onSubmit={handleSubmit((data) => {
                    axios({
                        method: "POST",
                        url: "/userData",
                        data: {
                            memberNumber: data.memberNumber,
                            memberPassword: data.memberPassword,
                        }
                    }).then((res) => {
                        if (res.data.message === undefined) {
                            console.log(res.data)
                        } else if (res.data.message.slice(0, 4) === "<SRT") {
                            alert('로그인 성공 !')
                        }
                    })
                })}>
                    <TextField
                        id="memberNumber"
                        label="회원번호"
                        placeholder="ex)11111111 숫자로만 입력"
                        {...register("memberNumber", {
                            required: "회원번호는 필수 입력입니다.",
                        })}
                    />
                    {errors.memberNumber && <small role="alert">{errors.memberNumber.message}</small>}
                    <TextField
                        type="password"
                        label="비밀번호"
                        placeholder="Password"
                        {...register("memberPassword", {
                            required: "비밀번호는 필수 입력입니다.",
                            minLength: {
                                value: 6,
                                message: "6자리 이상 비밀번호를 사용하세요.",
                            },
                        })}
                    />
                    {errors.memberPassword && <small role="alert">{errors.memberPassword.message}</small>}
                    <Button type='submit' variant="contained">로그인</Button>
                    <div className='srt-signup'>
                        <span>SRT 회원이 아니신가요?</span>
                        <a href='https://etk.srail.kr/cmc/02/selectJoinInfo.do?pageId=TK0702000000' target='blank'>회원가입</a>
                    </div>
                </form>
            </div>
        </div>
    )
}
profile
화이팅

0개의 댓글