Admin Project - 2일차 정규식 form validcheck

Seuling·2022년 7월 22일
1

프로젝트

목록 보기
7/7
post-thumbnail

오늘 한 일

이슈카드

이슈카드 처음 사용!
이슈 카드를 생성하고, 커밋할 때 git commit -m 'feat #1 : 첫번째 테스트' 이런식으로 #이슈번호를 해주면 연결이된다!

정규식 활용한 유효성 검사

<Form/>

  const Form = (props: Props) => {
 
  const [nickInput, setNickInput] = useState("");
  const [emailInput, setEmailInput] = useState("");
  const [phoneInput, setPhoneInput] = useState("");
  const [dateInput, setDateInput] = useState("");

    <FormStyle.DataTitle>이름</FormStyle.DataTitle>
      <ValidationInput
      type="text" name="name" placeholder="홍길동"
    value={nickInput}
    setValue={setNickInput}
    maxValue={10}
    regexCheck={regex.nickname}
    defaultText="닉네임을 입력해주세요!"
    errorText="한글로 3자 이상 입력해주세요."
  />
    
    <FormStyle.DataTitle>생년월일</FormStyle.DataTitle>
      <ValidationInput type="text" name="birthday" placeholder="YYYY.MM.DD" 
       value={dateInput}
      setValue={setDateInput}  maxValue={10} regexCheck={regex.date} defaultText="생년월일을 입력해주세요!"
      errorText="YYYY.MM.DD 형태로 입력해주세요!"
      />
    
     <FormStyle.DataTitle>이메일</FormStyle.DataTitle>
      <ValidationInput type="email" name="email" placeholder="MYD@snplab.com"
      value={emailInput}
      setValue={setEmailInput}
      regexCheck={regex.email}
      defaultText="이메일을 입력해주세요!"
      errorText="이메일 양식을 맞춰주세요!" maxValue={undefined}
       />
    
    <FormStyle.DataTitle>연락처</FormStyle.DataTitle>
      <ValidationInput
        type="tel"
        name="contact"
        placeholder="'-'없이 입력해 주세요"
        value={phoneInput}
    setValue={setPhoneInput}
    regexCheck={regex.phone}
    maxValue={11}
    defaultText="연락처를 입력해주세요!"
    errorText="연락처 01012345678 형태로 입력해주세요!"

<ValidationInput/>

import React, { useState } from "react";
import * as FormStyle from "../components/form/Form.styled"

export default function ValidationInput({
  label,
  type,
  value,
  maxValue,
  setValue,
  regexCheck,
  errorText,
  defaultText,
  placeholder,

}:any) {
  const [isError, setIsError] = useState(false);
  const [helperText, setHelperText] = useState(defaultText);

  
  const HandleOnChange = (e: { target: { value: string | any[]; }; }) => {
    //최대값이 지정되어있으면 value를 저장하지 않는다.
    if (maxValue && maxValue < e.target.value.length) return;

    setValue(e.target.value);

    //공백인 경우 defaultText로 바꾼다.
    if (e.target.value === "") {
      return setHelperText(defaultText);
    }
 
    if (regexCheck) {
      // 정규표현식체크가 통과되면 successText를 송출하고 아니면 errorText를 송출한다
      if (regexCheck.test(e.target.value)) {
        return setIsError(false);
      }else{
        setIsError(true);
        setHelperText(errorText);
      }
    }
  };
  
  return (
    <div>
         <FormStyle.DataInput
        type={type}
        onChange={HandleOnChange}
        value={value}
        placeholder={placeholder}
      />
      {isError&&<div>{helperText}</div>}
    </div>
  );
}

ValidationInput.defaultProps = {
  type: "text",
  label: "",
  value: ""
};

<Regex/>

//한국어+글자수(3글자 이상,10글자 이하)
const nickname = /^[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]{3,10}$/;

//email형식
const email = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;

//phone형식 (숫자만, 11글자 이하)
const phone =  /^[0-9]{11}/g;

const date = /^(([0-9]+).{4}([0-9]+).{2}([0-9]+){2})/g;


const regex = { nickname, email, phone, date };

export default regex;

https://regexr.com/ 에서 미리 테스트해볼 수 있다! 완전 유용!!

이렇게만 하는데는 어려움이 없었다. 하지만, 아쉬운점을 개선하려다 하루종일 시간을 쏟았다.

트러블슈팅

이부분을 보고 <ValidationInput/>에서 value값과 phoneInput 값과 동일 할 때 이런식으로 setValue를 해주면 되지 않을까 ? 라는 생각을 했다.

if(value === phoneInput){
    setValue(e.target.value).replace(/-/g,"")
}else{
    setValue(e.target.value);
}

그러다, setValue니까,

const [nickInput, setNickInput] = useState("");

setValue는 setNickInput 은 그럼 바꿔주는 거니까, 그전의 상태를 하나 바꾼값을 setValue로 넣어줘야지
중간에 temp같은걸 넣어보자!

그럼에도 안되었다... 왜 ????
setValue는 일단 반환값이 없답니다!!!!

상위 컴포넌트인 <Form/> 에서 이부분을 추가하였다.

const [phoneTempInput, setPhoneTempInput] = useState("");

하위 컴포넌트인 <ValidationInput/>에서 값을 반환해도 상위로 리코일을 쓰지않으면 올릴수 없지않나? 라는 생각에,

<ValidationInput/>컴포넌트에서 이부분을 다시 선언해주었다.

const [phoneTempInput, setPhoneTempInput] = useState("");
if(value === phoneInput){
      console.log("value===phoneinput")
      console.log(e.target.value)
    }

그후 value 값이 phoneInput인 값에서만 콘솔에 찍히도록 해보았고,

아주 잘 들어왔다.

if(value === phoneInput){
      console.log("value===phoneinput")
      setPhoneTempInput(e.target.value)
      console.log(phoneTempInput)
    }

이부분을 잘못한거같은데 ……….
setValue에 setPhoneInput이 전달되어서 들어와야한다.....

다시 이부분을 상위 컴포넌트인 <Form/>에 넣어줫다.

const [phoneTempInput, setPhoneTempInput] = useState("");

휴 .... 여기서 일단 스탑!!!

또다른 문제점 : 아무값도 없을때 에러메시지를 먼저 보이지 않기

처음을 False로 해줌으로 간단히 해결!

const [isError, setIsError] = useState(false);

아쉬움

해보고싶었는데 못하였다.
만약 이름을 입력할 때 한글만 입력되어야하는데, 영어가 들어오면 입력을 막는것을 해보고 싶었다.
또한, 생년월일 부분에 있어서 YYYY.MM.DD로 입력받아야하고 YYYYM이 되면 M이 지워지고 에러메시지를 띄워주거나 아니면 마지막에 .을 자동으로 입력하고 싶었지만 못하였다.

또한, form 같은 경우 react-hook-form을 사용하면 간단하게 만들 수 있다하여 두가지 버전으로 구현해보고싶었지만, 팀프로젝트에서 정규식으로 구현 하고 개인프로젝트에서 react-hook-form을 활용해봐야겠다!

reference
onChange 시에 바로바로 validation 해주는 input 만들기

[정규식 패턴] 내가 보려고 적어두는 자주 쓰는 정규식 표현

[JS] 📚 정규식 (RegExp) - 누구나 이해하기 쉽게 정리

Change date from YYYYMMDD to YYYY-MM-DD Javascript

[javascript] input태그 특수문자 입력 방지

state를 이용한 데이터 바인딩

profile
프론트엔드 개발자 항상 뭘 하고있는 슬링

0개의 댓글