
매니저앱에 로그인하기 위한 비밀번호는 숫자 6자리로만 이루어진다.
1. 동일한 숫자가 3번 연속되는 경우
2. 연속된 숫자가 3개 이상인 경우
위 두 가지 경우엔 이미지와 같이 안내 문구가 나온다. 이 유효성 검사를 위해 정규식을 사용했는데 이상하게 언제는 정규식에 일치하는 문자열이 잘 검색되고, 언제는 검색이 안 되는 경우가 있었다.
일단 코드를 보자.
const ERRORS = [
{
pattern: /(\d)\1\1/g,
message: '같은 숫자를 3개 이상 연속해서 사용하지 말아주세요.',
},
{
pattern: /(012|123|234|345|456|567|678|789)/g,
message: '연속된 숫자를 3개 이상 사용하지 말아주세요.',
},
];
const ChangePwdScreen = () => {
(...)
};
이렇게 Screen 컴포넌트 바깥쪽에 정규표현식과 메시지가 담긴 객체 배열을 만들어두었다.
비밀번호를 검증하는 함수는 ChangePwdScreen 함수형 컴포넌트 안쪽에 위치해있다. 비밀번호 유효성을 체크하기 위해 아래와 같은 코드를 사용했다.
const error = ERRORS.find((e) => e.pattern.test(password));
그런데 정말 이상하게 처음 설명한 두 가지 경우의 비밀번호를 입력해도 어떤 때는 error가 undefined로 나왔다.
알고보니 전역 탐색 플래그를 설정해서 test() 함수로 검색에 성공했을 때 lastIndex를 업데이트했기 때문에 그런거였다. MDN문서를 보면 전역 탐색 플래그(g)를 설정한 경우, exec() 또는 test() 함수로 일치하는 문자열 검색에 성공한 경우 lastIndex를 업데이트 한다고 나와있다. 그리고 두 번째부터 다시 함수를 호출하는 경우 lastIndex부터 검색을 시작한다. 또 검색에 실패했을 때는 lastIndex를 다시 0으로 초기화한다.
즉, '111247'일 때 '111'이 정규식 패턴에 일치하므로 lastIndex는 3으로 업데이트된다.
따라서 그 후에 '111963'으로 바꾸면 '9'부터 검색을 시작하므로 당연히 패턴에 일치하는 문자열을 찾을 수 없다.
lastIndex를 업데이트하는 방식은 전역 탐색 플래그를 설정한 경우이므로 정규식 패턴에서 /g 플래그를 빼줬다. 현재 상황에서 의미없는 플래그를 습관처럼 주지 말자..