개발/React

Nickname 설정을 위한 유효성 검사(이모지 완전히! 막기)

pizzaYami 2024. 3. 13.

 

Tars프로젝트를 진행하면서 Nickname의 유효성 검사 함수를 만들어야 했는데 생각보다 시간이 많이 들어가서 블로깅을 해보았다.

특히 이모지를 input에 입력조차 안되게 해야했는데 input.length가 자꾸 생성되어서 곤욕스러웠다.

 

기획에서 요구한 Nickname 설정 규칙은 다음과 같다.

  • 허용
    • 한글, 영어, 특수 문자, 숫자 허용
    • 외자(귤, ㅎ) 허용
    • 닉네임 중복 허용
  • 제한
    • 띄어쓰기 불가 - 띄어쓰기 막아버리기
    • 이모지 불가능 - information에 “이모지는 사용할 수 없어요“ 빨간색으로 변경, 이모지 지우면 기존으돌아감
    • 8자 제한 - 8자초과해서 입력 안되도록
    • 공란 - 확인 버튼 비활성화

닉네임 중복 허용하기 때문에 onChange가 될때마다 유효성검사가 되도록 원하였고 8자 제한을 하며 띄어쓰기, 이모지는 아예 입력이 안되도록 되길 원했다. 

 

이모지를 확인하는 정규식

const regex =
  /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|
  [\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|
  \ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|
  \ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|
  \ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|
  \u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|
  \u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|
  \ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g;

 

띄어쓰기와 이모지정규식이 있다면 replace를 이용해서 막았고 

// 띄어쓰기 막기
input = input.replace(' ', '');
// 이모지 막기
input = input.replace(regex, '');

 

8자 제한은 input태그의 maxLength를 이용해서 막았다.

 <input
        placeholder="닉네임을 입력해 주세요"
        value={nickname}
        onChange={(e) => handleNicknameChange(e)}
        maxLength={8}
      />

 

문제점

 

하지만 문제점이 있었다.

닉네임을 설정하고 보내야되는데 🙋🏻‍♂️처럼 특정 이모지를 input에 넣으면 삭제가 되지만 nickname.length가 존재하였다.

그래서 보이지 않는 어떤한 값이 닉네임으로 설정되는 사태가 발생하였다.

 

스택블리치에 실제로 🙋🏻‍♂️를 넣어보면 nickname.length가 존재하는 것을 확인할 수 있다.

 

 

해결책

여러가지 방법을 시도를 해보았지만 방법이 없어서 완전히 다른 방식으로 만들었다.

기획에서 요구한 Nickname 설정 규칙을 다시보면

  • 한글, 영어, 특수 문자, 숫자 허용

굳이 이모지를 막지 않아도 한글, 영어, 특수문자, 숫자만 허용하고 나머지는 싹다 막아버리면 되지 않을까?!

 

당장 시도해보았다.

 

한글, 영어, 숫자, 특수문자를 입력가능하게하는 함수를 정규식을 통해 함수를 만들었다.

function isValidNickname(nickname: string) {
  const regex =
    /^[가-힣\u3131-\u314E\u314F-\u3163a-zA-Z0-9!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]+$/;
  return regex.test(nickname);
}

 

그리고 input을 isValidNickname함수에 넣었을 때 true가 나오거나 input값이 ""이면 nickname이 설정되도록 하니깐.

아주 잘 작동하였다.

    if (isValidNickname(input) || input === '') {
      setNickname(input);
    }

 

🙋🏻‍♂️를 넣어도 nickname.length가 존재하지 않는걸 확인할 수 있다.

댓글