[항해 실전 프로젝트][React] 회원가입 기능 구현하기 (실시간 유효성 검사 에러 메시지 띄우기)

Carrie·2023년 8월 12일
1
post-thumbnail

유저의 편의성을 높이기 위해 버튼 클릭을 최소화한 깔끔한 UI의 회원가입 폼을 만들어보았다!

기능 설명

✔️ 가입하기 버튼을 누르지 않아도 사용자가 입력할 때 마다 유효성 검사 실패 에러메시지가 노출된다.
✔️ 아이디 중복 확인 버튼 없이 사용자가 아이디를 입력하면 이미 사용중인 아이디인지, 사용 가능한 아이디인지 바로 에러메시지가 노출된다.
✔️ 모든 조건을 충족하면 회원가입 요청을 서버에 보내서 회원가입을 완료한다!

작업 시작!

1. useState를 이용한 상태 설정

const [id, setId] = useState('');
const [password, setPassword] = useState('');
const [confirm, setConfirm] = useState('');

const [idError, setIdError] = useState('');
const [passwordError, setPasswordError] = useState('');
const [confirmError, setConfirmError] = useState('');

const [isIdCheck, setIsIdCheck] = useState(false); // 중복 검사를 했는지 안했는지
const [isIdAvailable, setIsIdAvailable] = useState(false); // 아이디 사용 가능한지 아닌지

아이디, 비밀번호, 비밀번호 확인을 위한 상태값과 각각의 에러메시지를 관리하기 위해 useState를 사용하여 상태를 설정하였다. 또한 중복 검사 여부 상태값 관리를 위한 설정도 해주었다.

2. onChangeHandler 구현

const onChangeIdHandler = (e) => {
    const idValue = e.target.value;
    setId(idValue);
    idCheckHandler(idValue);
  }

  const onChangePasswordHandler = (e) => {
    const { name, value } = e.target;
    if (name === 'password') {
      setPassword(value);
      passwordCheckHandler(value, confirm);
    } else {
      setConfirm(value);
      passwordCheckHandler(password, value);
    }
  }

사용자가 아이디와 비밀번호를 input창에 입력할 때마다 해당 값의 변화를 감지하고 업데이트하는 onChangeHandler를 구현하였다. 여기서 아이디, 비밀번호 유효성 검사 Handler를 호출한다.

3. 아이디 유효성 검사, 중복 검사 Handler 구현

  const idCheckHandler = async (id) => {
    const idRegex = /^[a-z\d]{5,10}$/;
    if (id === '') {
      setIdError('아이디를 입력해주세요.');
      setIsIdAvailable(false);
      return false;
    } else if (!idRegex.test(id)) {
      setIdError('아이디는 5~10자의 영소문자, 숫자만 입력 가능합니다.');
      setIsIdAvailable(false);
      return false;
    }
    try {
      const responseData = await idDuplicateCheck(id);
      if (responseData) {
        setIdError('사용 가능한 아이디입니다.');
        setIsIdCheck(true);
        setIsIdAvailable(true);
        return true;
      } else {
        setIdError('이미 사용중인 아이디입니다.');
        setIsIdAvailable(false);
        return false;
      }
    } catch (error) {
      alert('서버 오류입니다. 관리자에게 문의하세요.');
      console.error(error);
      return false;
    }
  }

먼저 유효성 검사를 실시하고, 유효한 형식의 아이디인 경우 서버에 중복 검사를 요청하여 중복 여부에 따른 에러메시지를 띄워준다.

4. 비밀번호 유효성 검사 Handler 구현

  const passwordCheckHandler = (password, confirm) => {
    const passwordRegex = /^[a-z\d!@*&-_]{8,16}$/;
    if (password === '') {
      setPasswordError('비밀번호를 입력해주세요.');
      return false;
    } else if (!passwordRegex.test(password)) {
      setPasswordError('비밀번호는 8~16자의 영소문자, 숫자, !@*&-_만 입력 가능합니다.');
      return false;
    } else if (confirm !== password) {
      setPasswordError('');
      setConfirmError('비밀번호가 일치하지 않습니다.');
      return false;
    } else {
      setPasswordError('');
      setConfirmError('');
      return true;
    }
  }

비밀번호 유효성 검사를 실시한다.

5. 회원가입 요청을 서버에 전송하는 Handler 구현

  const signupHandler = async (e) => {
    e.preventDefault();
    
    const idCheckresult = await idCheckHandler(id);
    if (idCheckresult) setIdError('');
    else return;
    if (!isIdCheck || !isIdAvailable) {
      alert('아이디 중복 검사를 해주세요.');
      return;
    }

    const passwordCheckResult = passwordCheckHandler(password, confirm);
    if (passwordCheckResult) { setPasswordError(''); setConfirmError(''); }
    else return;

    try {
      const responseData = await signup(id, password, confirm);
      if (responseData) {
        localStorage.setItem('loginId', id);
        setOpenModal(true);
      } else {
        alert('회원가입에 실패하였습니다. 다시 시도해주세요.');
      }
    } catch (error) {
      alert('회원가입에 실패하였습니다. 다시 시도해주세요.');
      console.error(error);
    }
  }

아이디와, 비밀번호 유효성 검사를 실시하는 함수를 호출하고 모든 결과값이 true일 때 회원가입 요청을 서버에 전송한다.

6. 회원가입 UI 구현

  return (
    <>
      <SignupPageHeader />
      <Wrapper>
        <Form onSubmit={signupHandler}>
          <InputWrapper>
            <InputContainer>
              <label htmlFor='id'>아이디</label>
              <Input
                onChange={onChangeIdHandler}
                type="text"
                id='id'
                name='id'
                value={id}
                placeholder='아이디 입력'
                theme='underLine'
                maxLength={10}
              />
              {idError && <small className={isIdAvailable ? 'idAvailable' : ''}>{idError}</small>}
            </InputContainer>
            <InputContainer>
              <label htmlFor='id'>비밀번호</label>
              <Input
                onChange={onChangePasswordHandler}
                type="password"
                id='password'
                name='password'
                value={password}
                placeholder='비밀번호 입력'
                theme='underLine'
                maxLength={16}
              />
              {passwordError && <small>{passwordError}</small>}
              <Input
                onChange={onChangePasswordHandler}
                type="password"
                id='confirm'
                name='confirm'
                value={confirm}
                placeholder='비밀번호 확인'
                theme='underLine'
                maxLength={16}
              />
              {confirmError && <small>{confirmError}</small>}
            </InputContainer>
          </InputWrapper>
          <ButtonContainer>
            <button type='submit'>가입하기</button>
          </ButtonContainer>
        </Form>
        {setOpenModal ? openModal && (<SignupModal />) : null}
      </Wrapper>
    </>
  )

마지막으로 위와 같이 UI 구현하면 끝!
아래처럼 잘 작동한다😄

profile
Markup Developer🧑‍💻

0개의 댓글