HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🐣
프론트엔드 데브코스 4기 교육생
/
🍎
성기동팀
/
🪄
NIRVANA MANAGER
/
Login 페이지
Login 페이지
Login 페이지

Login 페이지

  • 이메일과 비밀번호를 입력하는 화면을 보여줍니다.
 
notion image

선언

  1. 상태
  • email : 이메일 입력값을 실시간으로 받아오기 위해 사용합니다.
  • password : 비밀번호 입력값을 실시간으로 받아오기 위해 사용합니다.
  • errorCatched : login API 를 요청할 때 에러가 발생하면 true 로 설정합니다.
    • 해당 state 가 true 일 경우 에러 메세지를 출력해줍니다.
  1. 선언
  • setUser : 전역 유저 상태를 저장하기 위한 함수입니다.
  • navigate : 로그인이 성공하면 메인 페이지로 이동하기 위해 사용합니다.
  • timer : 디바운싱 처리를 해주기 위한 타이머 ID 를 받습니다.

렌더링

다음 요소를 렌더링합니다.
UserInput 컴포넌트와 Button 컴포넌트의 props 에 맞게 값을 넣어줍니다.
Login 페이지에서 주의깊게 봐야할 prop 은 핸들링 함수입니다. (아래에서 설명합니다)
전체 코드는 다음과 같습니다.

UserInput 이벤트 핸들러

input 에 값을 입력 할때마다 디바운싱으로 email 이나 password 의 값을 바꿉니다.

Button 이벤트 핸들러

postLogInUser 라는 API 를 통해 email 과 password 로 로그인 요청을 시도합니다.
  • 성공
    • 전역적으로 유저 데이터를 저장하고, 명상 페이지로 이동합니다.
  • 실패
    • 에러를 출력하고 setErrorCatched 를 true 로 바꿉니다.
 
 
종류
페이지
작성자
const [email, setEmail] = useState<string>(''); const [password, setPassword] = useState<string>(''); const [errorCatched, setErrorCatched] = useState<boolean>(false); const setUser = useSetRecoilState(userState); const navigate = useNavigate(); let timer = 0;
<Logo /> <LoginForm> <UserInput name='email'/> <UserInput name='password'/> <Button label='로그인'/> <GoToSignUp /> // 회원가입 페이지로 이동합니다 </LoginForm>
<LoginContainer> <LogoContainer> <Logo /> </LogoContainer> <LoginForm onSubmit={handleSubmit}> <UserInput name={USER_INPUT.EMAIL.NAME} placeholder={USER_INPUT.EMAIL.PLACE_HOLDER} title={USER_INPUT.EMAIL.TITLE} handleChange={handleInputChange} show={errorCatched} errorMessage={USER_INPUT.ERROR_MESSAGE} /> <UserInput name={USER_INPUT.PASSWORD.NAME} placeholder={USER_INPUT.PASSWORD.PLACE_HOLDER} title={USER_INPUT.PASSWORD.TITLE} handleChange={handleInputChange} type={USER_INPUT.PASSWORD.TYPE} /> <ButtonContainer> <Button label='로그인' width={300} height={45} bold={false} dark={true} handleClick={() => handleSubmit} /> </ButtonContainer> <GoToSignUp /> </LoginForm> </LoginContainer>
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => { event.preventDefault(); const { name, value } = event.target; if (timer) { // 디바운싱을 위한 로직 clearTimeout(timer); } timer = setTimeout(() => { switch (name) { case USER_INPUT.EMAIL.NAME: // email type 일 경우 email 상태 변경 setEmail(value); break; case USER_INPUT.PASSWORD.NAME: setPassword(value); // password type 일 경우 상태 변경 break; default: break; } }, 200); // 0.2s 마다 마지막 이벤트만 실행합니다 };
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault(); postLogInUser({ email, password }) .then((res) => { const { user, token } = res.data; setUser({ ...user, token }); navigate('/meditation'); }) .catch((err) => { console.log(err); setErrorCatched(true); }); return; };