FrontEnd

[React📜] 로그인 회원가입 유효성 검사기능 구현 3가지

머털박사 2022. 8. 12. 15:54

해당 포스팅은 로그인 회원가입시 유효성 검사하는 방법에 대해 다룹니다.

💡 요약

  • React에서 유효성 검사하는 방법은 3가지가 있다. input 태그 고유 속성 사용, 라이브러리 없이 직접 script작성, 라이브러리 사용.
  • 간단한 유효성 검사는 직접 작성해도 된다.
  • 유효성 검사할 내용이 복잡해진다면 라이브러리를 사용하자. 라이브러리는 react hook form을 권장한다.

유효성 검사란

유효성 검사는 입력받은 데이터 값이 맞는지(유효한지) 확인하는 것을 의미합니다. 예를들면 비밀번호에 “8자리 이상 두 종류 이상의 문자 구성”라는 유효성 조건이 있다면 “1111”이라는 비밀번호를 입력할 경우 통과되지 않습니다.

React에서 유효성 검사를 구현하는 방법은 크게 3가지가 있습니다. 첫 번째는 html요소인 <input> 안의 속성을 활용하기, 두 번째는 javascript로 구현하기, 세 번째는 라이브러리를 사용하는 것입니다.

1. <Input> 속성으로 유효성 검사하기

첫 번째, HTML 태그인 <input> 요소 고유 속성을 사용한 유효성 검사입니다. 가장 기본적인 방법으로 유용한 속성으로는 required, pattern, minlength가 있습니다.

required

  <form>
      <input type="text" required></input>
      <button type="submit">제출</button>
  </form> 

위처럼 코드가 적힌 경우 input에 내용이 입력되지 않으면 제출되지 않습니다.

boolean값으로 양식이 전송되기 위해서 반드시 입력하거나 확인이 필요한 것. 대부분 모든 타입에 적용 가능합니다. ( text, search, url, tel, email, date, month, week, time, datetime-local, number, password, checkbox, radio, file )

pattern

    <form action="/examples/media/action_target.php" method="get">
        생년월일 : <input type="text" name="bday" pattern="[0-9]{6}" title="'yymmdd'와 같은 6자리 숫자"><br>
        <button type="submit">
    </form>

위처럼 pattern에는 정규식 패턴이 들어갑니다. 이때 title 속성도 사용해서 사용자에게 패턴 형식을 알려주는 것이 좋습니다.

해당 속성을 사용할 때는 title 속성을 사용해서 사용자에게 패턴 형식을 알려주는 것이 좋습니다. 대부분 브라우저에서 title로 설명을 표기하는 편입니다.

`<input type="text" pattern="^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,16}$">`  

최소 8자리에서 최대 16자리까지 숫자, 영문, 특수문자 각 1개 이상 포함되는 조건을 가진 input을 만들고 싶다면 위처럼 적을 수 있습니다.

password, text, tel 타입에 적용할 수 있습니다. 이 속성이 지정된 경우 value 가 pattern 속성에 적힌 정규식과 일치해야합니다. 대신 기존 정규식과 다르게 패턴 텍스트 주위에 슬래시를 넣으면 안됩니다.

minlength, maxlength

```
  <input type="password" minlength="8" maxlength="20" required></input>
  <-- 8자 이상 20자 이하인 비밀번호만 입력 가능-->
```

위의 예시는 8자 이상 20자 이하인 비밀번호만 입력 가능한 요소입니다. value의 최대, 최소 길이를 한정합니다. password, search, tel, text, url 타입에 적용시킬 수 있습니다. pattern처럼 정교한 정규식이 필요없고 길이 관련된 유효성 검사만 필요한 경우 사용하면 좋습니다.

2. script로 유효성 검사하기

두 번째, script를 작성해서 유효성 검사할 수 있습니다.

//some code

const [error, setError] = useState()

const onSubmit = async (form: RegisterFormType) => {
    setError(null);
    // validate
    const validation = {
      displayName: (text: string) => {
        if (text === '') {
          return '이름을 입력해주세요.';
        }
        if (text.length > 45) {
          return '이름은 최대 45자까지 입력 할 수 있습니다.';
        }
      },
      username: (text: string) => {
        if (!/^[a-z0-9-_]{3,16}$/.test(text)) {
          return '아이디는 3~16자의 알파벳,숫자,혹은 - _ 으로 이루어져야 합니다.';
        }
      },
      shortBio: (text: string) => {
        if (text.length > 140) {
          return `한 줄 소개는 140자 미만으로 입력해주세요. (현재 ${text.length}자)`;
        }
      },
    };

    const errorMessage =
      validation.displayName(form.displayName) ||
      validation.username(form.username) ||
      validation.shortBio(form.shortBio) ||
      null;

    if (errorMessage) {
      setError(errorMessage);
      return;
    }
}

위의 예시는 모듈 형식을 이용한 velog 클라이언트 회원가입 폼의 유효성 검사 로직입니다. 해당 함수는 submit 버튼을 눌렀을 때 사용됩니다. 일단 validation이라는 객체에 검사하고 싶은 요소에 관련된 함수 넣습니다.

이후 or연산자를 사용해 함수를 호출하고 파라미터에 검사 요소를 넣습니다. 함수를 통과하지 못하면 문자열, 통과하면 null이 반환됩니다.만약 반환값이 문자열일 경우에는 그 문자열을 useState로 선언한 error에 할당합니다.

<script>
  export default {
    data: () => ({
      valid: false,
      firstname: '',
      lastname: '',
      nameRules: [
        v => !!v || 'Name is required',
        v => v.length <= 10 || 'Name must be less than 10 characters',
      ],
      email: '',
      emailRules: [
        v => !!v || 'E-mail is required',
        v => /.+@.+/.test(v) || 'E-mail must be valid',
      ],
    }),
  }
</script>

해당 코드는 vue 라이브러리의 프레임워크인 vuetify 유효성 검사 로직입니다. 익숙하지 않지만 로직만 확인하기 위해 가져왔습니다. 여기서도 or연산자를 활용한 비슷한 로직을 볼 수 있습니다.

요소를 선언하고 해당 요소에 :rules 라는 속성을 부여합니다. 이후 script에서 해당 요소의 규칙을 부여합니다. nameRules 경우 이름이 없으면 ‘Name is required’라는 문자열을 반환합니다. 이와 같이 script 상에서 유효성 검사는 주로 정규식과 or 연산자를 활용하여 진행됩니다.

3. 라이브러리로 유효성 검사하기

세 번째, 이미 구현된 라이브러리를 사용해서 유효성 검사하는 방법입니다. 스크립트로 state를 선언하고 유효성 검사를 하면 코드가 방대해집니다. 리액트에는 유능한 개발자가 폼 유효성 검사를 위해 만든 라이브러리가 존재합니다. 그 중 가장 유명한 것은 Formik과 Reack Hook Form 입니다.

이름 다운로드수 stars updated size
formik 1,896,564 30k a year ago 13.0kb
react-hook-form 1,897,023 29k 12 days ago 8.6kb

2022년 7월 13일 기준 react-hook-form이 다운로드 수가 미세하게 높습니다. 원래는 formik의 다운로드 수가 더 많았는데 따라잡았네요.

formik은 1. 폼 상태의 값 가져오기2. 유효성 검사 및 오류메세지 3. 제출 양식에 대한 간단한 API를 제공해줍니다.

Reack Hook Form도 formik과 똑같은 기능을 제공합니다. 다른 점은 리랜더링 횟수입니다. formik은 provider방식으로 form내에 있는 모든 컴포넌트들이 동일한 상태를 공유하고 사용자의 입력할 때마다 리랜더링이 발생합니다. React-Hook-From은 이 과정이 최소화 하도록 설계되어 렌더링이 최소화됩니다.

import React from 'react';
import { useFormik } from 'formik';

const SignupForm = () => {
  // Pass the useFormik() hook initial form values and a submit function that will
  // be called when the form is submitted
  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>
  );
};

위는 이메일 유효성 검사를 하기 위한 formik 예시 코드이고

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

function App() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();
  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('firstName')} />
      <input {...register('lastName', { required: true })} />
      {errors.lastName && <p>Last name is required.</p>}
      <input {...register('age', { pattern: /\d+/ })} />
      {errors.age && <p>Please enter number for age.</p>}
      <input type="submit" />
    </form>
  );
}

위는 코드는 이름과 나이를 검사하기 위한 React Hook form의 예시입니다. 태그 안에서 props로 패턴을 정의할 수 있어서 한 눈에 봤을 때 코드가 훨씬 짧습니다.

이 사진은 React-Hook-Form 사이트에서 제공하는 간단한 비교입니다.


참고 출처

**
FAQs**

React Hook Form VS Formik

Formik