develop

react로 회원가입(2)-onBlur, trim, 정규식

crab. 2023. 1. 20. 16:09

포커스 아웃시 유효성 검사

  • 요즘의 웹서비스들은 따로 중복검사 버튼을 누르지 않아도 유저의 포커스 아웃(기입칸외의 다른 곳을 클릭)시 유효성 검사를 하게 되어있다.(과거에도 많이 그랬다면.. 할 말은 없다)
  • 이것을 구현하려면 기본적으로 input 태그의 onBlur속성을 알아야 한다.

onBlur

  • onFocus가 input창이 포커스되었을 때 호출할 함수를 사용한다면
  • onBlur는 input창이 포커스아웃되었을 때 호출할 함수를 사용한다.
				<input
                    ref={idRef}
                    type="id"
                    value={id}
                    onChange={onChangeId}
                    placeholder="이메일을 입력해 주세요"
                    onBlur={onClickIdDup}
                    data-testid="idInput"
                  />
  • 이런식으로 사용한다면 포커스아웃 될때마다 onClickIdDup이라는 함수를 호출하며 유효성 검사를 할 수 있다.
const onClickIdDup = useCallback(
    e => {
      e.preventDefault();
      if (!id.trim()) {
        setIdTrim(true);
        return;
      }
      setIdTrim(false);
      idChecker();
      dispatch(__duplicate_check(id));
      setIdDupCheck(true);
      if (!id.trim()) {
        setIdNotice(true);
        return;
      }
      setIdNotice(false);
    },
    [dispatch, id, idChecker],
  );
  • 앞서 설명했던 useCallback을 다시 여기서 설명하자면
  • 의존성 배열에 dispatch, id, idChecker가 들어가 있다.
    • 그 이유는 이 onClickIdDup 함수가 dispatch, id, idChecker의 값이 변할때마다
    • 이 함수를 재생성해야 하기 때문이다.
    • 역으로 생각해보면 이 함수는 dispatch와 id, idChecker의 값에 의존하고 있다는 뜻인데 어떻게 그런것인지 하나씩 풀어나가보자.
    • https://narup.tistory.com/220

공백을 확인하는 법

  • 회원가입에서 유효성을 검사할 때 제일 먼저 하는 것은 유저가 공백으로 넘어가지는 않았나 하는 점이다.
  • 여기서 사용되는 함수는 trim() 이다.
  • trim은 문자열 앞 뒤의 공백을 없애주는 함수인데 이게 앞에! 가 붙는다면 공백이거나 블랭크만 있을경우 true를 반환하게 된다.
  • const [idTrim, setIdTrim] = useState(false); 이렇게 설정하면
  • idTrim이 true일 경우 유저가 기입하지 않았거나 블랭크로 넣었다는 것을 알 수 있다.
  • 이후에는 return을 넣어줘 굳이 코드들을 실행시키지 않는다.
  • {idTrim && !id && <span>필수 입력 정보입니다</span>} 이후 input창 밑에 에러메시지를 이렇게 설정해 주면 공백확인이 끝이 난다.
    • 여기서 idTrim 과 !id를 같이 넣어준 이유는
    • idTrim만 넣어주게 되면 처음에 유저가 클릭하고 빈칸으로 넘어갔을때는 잡지만 실시간으로 onChange되며 유저가 값을 넣었을 때는 잡지 못하기 때문이며
    • 반대로 !id(!id는 값이 넣어있지 않다면 true가 된다.)는 기입할 경우 에러가 해제 되지만 처음부터 계속 에러로 표시 되기 때문에 상호보완적인 관계이다.

정규식 이용

  • 공백을 넘었다면 onBlur함수 내에서 setIdTrim(false); 를 해줌으로써 확실하게 공백에러를 넘어가 준다.
  • 이후 idChecker로 넘어간다.
const idChecker = useCallback(() => {
    if (!id.trim()) {
      setIdError(true);
      setIdNotice(true);
      return false;
    }
    if (!idFilter(id)) {
      setIdError(true);
      setIdNotice(true);
      return false;
    }
    setIdError(false);
    return true;
  }, [idFilter, id]);
  • idChecker 또한 useCallback으로 감싸져 있는데 이는 idFilter와 id값에만 의존하는 함수이며, 다른 상황에는 리렌더링 하지 않는다는 뜻이다.
  • 우선 다시금 공백을 확인해준다.
  • 이후 만약 공백이라면 ex) 유저가 썼다가 다시 지운 경우 error와 notice를 true로 해준다.
    • error의 경우 원래 false이지만 notice의 경우는 원래 true였다.
    • 이 notice값은 우선 회원가입의 경우 만약 아래 에러메시지 칸에 무언가 쓰여져 있게 하고 싶을 때 쓰는 것이며 에러가 나면 유저가 다시 값을 다 지웠을 때 에러를 없애기 위해 true로 바꾸는 것이다.
    • 다만 나의 경우 처음 시작할 때 안내메시지가 에러메시지 칸에 나오지 않으므로 거의 기능을 상실했고 조만간 리팩토링을 한다면 지워야 한다.
const idFilter = useCallback(id => {
    const filter = /[a-z0-9]+@[a-z]+\.[a-z]{2,3}/;
    return filter.test(id);
  }, []);
  • 이후 idFilter로 유효성 검사를 해주는 데 이때 정규식이 이용된다.
  • 정규식에 관한 내용은 https://velog.io/@moolbum/JavaScript-정규표현식
    • 여기가 좋다.
  • 여기서도 useCallback을 사용하는데 의존하는 state가 없으므로 빈 배열로 두었다(id는 가져와서 변경하기만 할뿐 id가 바뀐다 해서 idFilter함수가 리렌더링 될 필요가 없다.)
  • 이후 정규식의 test메서드를 통해 검사를 하고 에러라면 idError를 true로 바꿔준다.
  • 여기서 idFilter값을 그대로 사용하지 않는 이유는 함수 하나에서 공백과 유효성을 검사하고 이를 하나의 에러로 보낼 것이기 때문이다.
    • (함수의 추상화? 모듈화? 클린코드와 관련된 리팩토링 부분 같은데 나중에 기회가 된다면 리팩토링에 대해 공부해보고 싶다.)
  • 이후 정규식을 통과하면 idError의 값을 false로 바꿔준다.
  • idFilter에서 사용되는 state는 idFilter와 id만이므로 useCallback의 의존성배열에는 두 값만 들어간다.
  • 그 다음에는 중복을 검사한다.

레퍼런스 주소

https://itchallenger.tistory.com/258

https://velog.io/@ashnamuh/React의-useReducer-useCallback-useMemo-제대로-알고-사용하기

https://narup.tistory.com/220

https://www.daleseo.com/react-hooks-use-callback/

https://velog.io/@moolbum/JavaScript-정규표현식

https://kkk-kkk.tistory.com/entry/예제-9-16-onfocus와-onblur-이름을-입력하지-않고-다른-창으로-갈-수-없음

https://velog.io/@niboo/React-onFocus-와-onBlur이벤트를-사용하여-인풋창-색상-변경하기

https://velog.io/@niboo/React-회원가입-페이지-유효성-검사하기