[React]로그인, 회원가입 컴포넌트 구현하기(1/2 - 로그인)

전유덕·2024년 8월 16일
0
post-thumbnail

개요

회원가입, 로그인 등 인증관련 부분에 대한 깊이 있는 학습을 위해 고민하던 중..
미니프로젝트를 함께 진행했던 백엔드 개발자 한 분과 회원기반의 간단한 가계부 프로젝트를 진행하게 되었습니다.

이번 포스팅에서는 React와 React Router를 사용하여 사용자 인증을 처리하는 동적 로그인 컴포넌트를 개발하는 과정을 살펴보겠습니다.

백엔드측의 Api가 아직 완성되지 않아 이를 제외한 부분에 대해서만 작성하겠습니다.(추후 업데이트 예정)

컴포넌트 개요

Login 컴포넌트는 이메일과 비밀번호를 입력받아 사용자를 인증하는 역할을 수행합니다. 이를 위해 React의 상태 관리와 이벤트 처리, React Router의 페이지 이동 기능을 활용합니다.

상태 관리

React의 useState 훅을 사용하여 컴포넌트 상태를 관리합니다. 여기에는 입력 필드 값, 에러 메시지, 폼 유효성, 로딩 상태 등이 포함됩니다.

// 로딩 상태 관리 훅
const [isLoading, setIsLoading] = useState(false);

// 입력 필드 값 관리 훅
const [values, setValues] = useState({
  id: "",
  password: "",
});

// 유효성 검사 메시지 관리 훅
const [message, setMessage] = useState({
  id: "",
  password: "",
});

// 폼 유효성 관리 훅
const [isFormValid, setIsFormValid] = useState(false);

유효성 검사

이메일과 비밀번호의 유효성을 검증하기 위해 정규식을 사용합니다. 각각의 정규식은 아래와 같은 형식을 따릅니다.

  • 이메일 정규식: 이메일 주소의 형식이 올바른지 검사합니다.
  • 비밀번호 정규식: 비밀번호가 영문, 숫자, 특수문자를 포함하고, 8자 이상 15자 이하인지 검사합니다.
// 이메일 정규식
const idReg = /^[A-Za-z0-9]([-_.]?[A-Za-z0-9])*@[A-Za-z0-9]([-_.]?[A-Za-z0-9])*\.[A-Za-z]{2,3}$/;

// 패스워드 정규식
const passwordReg = /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,15}$/;

handleValidation 함수는 입력된 값이 정규식에 맞는지 검증하고, 오류 메시지를 설정합니다.

const handleValidation = (field, value) => {
  let errorMsg = ""; // 에러 메시지 초기화
  switch (field) {
    case "id":
      errorMsg =
        value.trim() === "" // 입력 값이 비어있는지 확인
          ? "이메일을 입력해주세요." // 입력 값이 비어있을 때 에러메시지
          : idReg.test(value) // 정규식 검사
          ? "" // 이메일 형식이 올바른 경우
          : "올바른 이메일을 입력해주세요."; // 이메일 형식이 올바르지 않은 경우
      break;
    case "password":
      errorMsg =
        value.trim() === "" // 입력 값이 비어있는지 확인
          ? "비밀번호를 입력해주세요." // 입력 값이 비어있을 때 에러메시지
          : passwordReg.test(value) // 정규식 검사
          ? "" // 비밀번호 형식이 올바른 경우
          : "영문,숫자,특수문자 포함 8자 이상 입력해주세요."; // 비밀번호 형식이 올바르지 않은 경우
      break;
    default:
      break;
  }
  setMessage((prev) => ({ ...prev, [field]: errorMsg })); // 에러 메시지 상태 업데이트
};

폼 유효성 관리

useEffect를 활용하여 입력 필드 값과 에러 메시지를 모니터링하며 폼의 유효성을 관리합니다.

useEffect(() => {
  // 모든 입력 값이 채워져 있는지 확인
  const areAllValuesProvided = Object.values(values).every(
    (value) => value.trim() !== ""
  );
  // 모든 메시지가 비어있는지 확인하여 폼의 유효성 상태를 설정
  const isEveryMessageEmpty = Object.values(message).every(
    (msg) => msg === ""
  );
  // 입력 값이 모두 제공되었고, 모든 유효성 검사 메시지가 비어있다면 폼이 활성화됨
  setIsFormValid(areAllValuesProvided && isEveryMessageEmpty);
}, [values, message]);

로그인 핸들러

로그인 버튼 클릭 시 호출되는 logInHandler 함수는 폼의 유효성을 검사하고, 유효한 경우 로그인을 처리합니다. 성공적인 로그인 후에는 페이지 이동이 이루어집니다.

const logInHandler = async (e) => {
  e.preventDefault();
  setIsLoading(true);

  // 입력 필드가 비어 있는 경우 에러 메시지 설정
  handleValidation("id", values.id);
  handleValidation("password", values.password);

  if (!isFormValid) {
    setIsLoading(false); // 폼 유효성 검사 실패 시 로딩 상태 비활성화
    return;
  }

  try {
    // 로그인 요청 처리
    // 예시: const response = await fetch("/public-api/v1/member/login", {...});
    navigate("/day");
  } catch (error) {
    // 오류 처리
    if (axios.isAxiosError(error)) {
      const errorMessage = error.response?.data.message;
      if (errorMessage === "가입된 이메일이 이미 존재합니다.") {
        setMessage((prev) => ({
          ...prev,
          id: "이미 가입된 이메일입니다.",
        }));
      }
    }
  } finally {
    setIsLoading(false); // 로그인 프로세스 종료, 텍스트 복원을 위한 상태 변경
  }
};

입력 필드 변경 핸들러

handleInputChange 함수는 입력 필드의 변경을 감지하여 상태를 업데이트합니다.

const handleInputChange = (e) => {
  const { name, value } = e.target; // 입력 필드 이름과 값 추출
  setValues((prev) => ({ ...prev, [name]: value })); // 입력 값 상태 업데이트
  handleValidation(name, value); // 입력 값에 대한 유효성 검사
};

2편 보러가기 - 회원가입

profile
zi존 개발자 되고싶다ㅏㅏ(훈수 대환영!)

0개의 댓글