[Next13 + TypeScript] 비밀번호 재설정 _ 이메일과 인증번호를 조건에 맞게 검사하기

ezi·2023년 9월 8일
0

🍯 1. 이메일 입력 시 emailRegex를 설정하여 이메일 조건에 충족하여 입력되도록

// 부모 컴포넌트
const PasswordFind = () => {
  const [email, setEmail] = useState('');

  const handleEmailChange = (value: string) => {
    setEmail(value);
    // console.log('email:', email);
  };

  return (
    <>
      <PasswordFindCotainer>
        <PasswordFindTitle>비밀번호 찾기</PasswordFindTitle>
        <PasswordFindInputWrap>
          ..
          <PasswordEmailTextField
            title="이메일"
            category="email"
            buttonText="이메일 인증"
            placeholder="이메일을 입력해주세요"
            required="올바른 이메일 형식으로 입력해주세요"
            onChange={handleEmailChange}
            name={name}
          />
         <PasswordCodeTextField
          title="인증번호"
          category="number"
          buttonText="확인"
          placeholder="인증 번호를 입력해주세요"
          required="숫자만 입력해주세요"
          email={email}
          onConfirmationChange={handleConfirmationChange}
        />
         ..
        </PasswordFindInputWrap>
      </PasswordFindCotainer>
    </>
  );
};
export default PasswordFind;
//PasswordEmailTextField

interface TextBtnFieldProps {
  title: string;
  type: string;
  placeholder: string;
  required?: string;
  buttonText: string;
  category: 'email';
  onValueChange?: (value: string) => void;
  onClick: () => void;
  onChange: (value: string) => void;
  name: string;
}

const PasswordEmailTextField = ({
  title,
  type,
  placeholder,
  required,
  buttonText,
  category,
  onValueChange,
  onClick,
  name,
  onChange = () => null,
}: TextBtnFieldProps) => {
  const [email, setEmail] = useState('');
  const [isValid, setIsValid] = useState(false);
  const [isEdited, setIsEdited] = useState(false);
  const [hasValue, setHasValue] = useState(false);

  const validateInput = (value: string, validationCategory: 'email') => {
    if (validationCategory === 'email') {
      const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
      setEmail(value);
      return emailRegex.test(value);
    }
    return false;
  };

  const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
    const inputValue = event.currentTarget.value;
    const isInputValid = validateInput(inputValue, category);
    setIsValid(isInputValid);
    setIsEdited(true);
    setHasValue(inputValue.length > 0);
    setEmail(inputValue);

    if (category === 'email' && inputValue.length === 0) {
      setIsValid(false);
    }

    if (onValueChange) {
      onValueChange(inputValue);
    }
  };

  return (
    <>
      <TextBtnFieldWrap>
        <TextBtnFieldTitle>{title}</TextBtnFieldTitle>
        <TextBtnWrap>
          <TextBtnFieldInput
            type={type}
            placeholder={placeholder}
            isValid={isValid}
            onChange={handleInputChange}
          />
          ..
        </TextBtnWrap>
        {!isValid && isEdited && <FieldRequired>{required}</FieldRequired>}
      </TextBtnFieldWrap>
    </>
  );
};

export default PasswordEmailTextField;

이메일의 조건 검사 형식은 아래와 같다.

const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

전체적인 코드의 흐름을 설명하자면,

TextBtnFieldInput onChange={handleInputChange} 변화할 때 handleInputChange 함수가 작동하도록 하였다.

handleInputChange 함수는 입력받은 값을 inputValue 에 저장하고
이메일 검사를 해주도록 만든 validateInput 함수에 적용하여 검사하는 것이다.

🍯 2. 인증번호 입력 시, numericRegex 를 설정하여 숫자만 입력되도록

부모컴포넌트는 이메일 조건을 확인하는 부분 상단에 작성한 코드와 같다.

//PasswordCodeTextField

...

interface TextBtnFieldProps {
  title: string;
  type: string;
  placeholder: string;
  required?: string;
  buttonText: string;
  category: 'number';
  onValueChange?: (value: string) => void;
  onClick: () => void;
  email: string;
  onConfirmationChange: (isValid: boolean) => void;
}

const PasswordCodeTextField = ({
  title,
  type,
  placeholder,
  required,
  buttonText,
  category,
  onValueChange,
  onClick,
  email,
  onConfirmationChange,
}: TextBtnFieldProps) => {
  const [authCode, setAuthCode] = useState('');
  const [isValid, setIsValid] = useState(false);
  const [isEdited, setIsEdited] = useState(false);
  const [hasValue, setHasValue] = useState(false);
  
  useEffect(() => {
    console.log('email', email);
  }, [email]);

  ...

  const validateInput = (value: string, validationCategory: 'number') => {
    if (validationCategory === 'number') {
      const numericRegex = /^(|[0-9]*)$/;
      return numericRegex.test(value);
    }
    return false;
  };

  const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
    const inputValue = event.currentTarget.value;
    const isInputValid = validateInput(inputValue, category);
    setIsValid(isInputValid);
    setIsEdited(true);
    setHasValue(inputValue.length > 0);
    setAuthCode(inputValue);

    if (category === 'number' && inputValue.length === 0) {
      setIsValid(false);
    }

    if (onValueChange) {
      onValueChange(inputValue);
    }
  };

  return (
    <>
      <TextBtnFieldWrap>
        <TextBtnFieldTitle>{title}</TextBtnFieldTitle>
        <TextBtnWrap>
          <TextBtnFieldInput
            type={type}
            placeholder={placeholder}
            isValid={isValid}
            onChange={handleInputChange}
          />
         ...
        </TextBtnWrap>
        {!isValid && isEdited && <FieldRequired>{required}</FieldRequired>}
      </TextBtnFieldWrap>
    </>
  );
};
export default PasswordCodeTextField;

인증번호 조건 검사 형식은 아래와 같다.

참고로, 인증번호는 무조건 숫자로 구성되어있었고 이 조건에 맞게 설정했다.

  const numericRegex = /^(|[0-9]*)$/;

전체적인 코드의 흐름은 이메일 조건 검사와 비슷하기 때문에 생략한다.

profile
차곡차곡

0개의 댓글