본문 바로가기
Web dev/기능구현

Todo 앱 구현하기 1. (회원가입, 로그인)

by growingTangerine 2023. 6. 13.

배포링크

 

Gyuri's Todo App

 

wanted-pre-onboarding-frontend-liard.vercel.app

깃허브 리포지터리 링크

 

GitHub - ImGyuriKim/wanted-pre-onboarding-frontend

Contribute to ImGyuriKim/wanted-pre-onboarding-frontend development by creating an account on GitHub.

github.com

원티드 프리온보딩 지원 과제로 Todo앱을 구현하게 되었다. 백엔드 API는 주어지는 상황이었고, API 문서를 참고하여 

 

- 회원가입

- 로그인

- todo CRUD 

 

이렇게 크게 3가지를 구현하는 과제였다. 

 

먼저, 그 중 회원가입과 로그인 기능을 구현한 과정을 기록해보고자 한다. 

 

1. 요구사항 정리하기

- 이메일, 비밀번호 유효성 검사 (이메일은 @ 문자가 들어갔는지, 비밀번호는 8자리 이상인지 확인)

- 이메일, 비밀번호 유효성 검사 통과 시 로그인/회원가입하기 버튼 disabled 가 false로 꺼지도록 구현

- 로그인 시 발급되는 JWT access token은 localStorage에 저장

- localStorage에 access token이 있을 시, 로그인 및 회원가입 페이지로 접근 시 todo 페이지로 리다이렉트

- localStorage에 access token이 없을 시, todo 페이지로 접근 시 로그인 페이지로 리다이렉트

 

2. 구현하기 전 구조 잡기 및 라우팅

위의 요구사항을 파악하여, src 하위 폴더에 pages를 만들어 총 네개의 페이지를 컴포넌트로 만들어주었다.

 

Home.js - 랜딩 페이지

Signin.js - 로그인 페이지

Signup.js - 회원가입 페이지

Todo.js - todo 페이지

 

그리고 이 네가지 페이지의 라우팅을 react-router 라이브러리를 이용하여 App.js에 정리해주었다. 

페이지간 이동을 할 수 있는 UI인 Nav bar 컴포넌트도 생성하여 어느 페이지에서나 같은 위치에서 볼 수 있도록 App.js에 작성했다. 

또, 로그아웃 기능을 구현한 Logout 컴포넌트를 로그인 여부를 파악하여 조건부 렌더링시켜주었다. 

 

3. 컴포넌트 구현하기

 - Signin / Signup 컴포넌트

로그인, 회원가입에서 요구하는 사항은 거의 동일한데, JWT access token을 받아오는 로직만 다르다. 

 

우선, 로그인이 되어있는 상태에서 todo로 리다이렉트 해주는 코드를 컴포넌트 내부 제일 상단에 위치시켜주었다. 

그 다음으로는 fetch 요청에 사용할 baseURL, 유효성 검사용 상태를 useState를 이용해 관리해주었다.

 

allValid라는 변수는 이후 로그인/회원가입 버튼을 disabled 속성 값으로 바로 boolean으로 이용하기 위해 이메일과 비밀번호 모두 유효할 때만 true가 되도록 값을 할당해주었다. 

버튼 disabled 속성 관리

 

또한, 아래 코드에서처럼 input의 onChange에서 핸들러 함수로 바로 유효성 검사 조건문을 작성해주고, isValid 를 각각 true로 변경해주었다. 그리고 유효 여부에 따라 유효하지 않을 때 붉은색으로 "비밀번호/이메일을 확인해주세요" 라는 문구가 뜨도록 div태그를 작성해주었다. 

 

비밀번호 유효성 검사 / 이메일 또한 동일한 구성이다.
사용자에게 유효성 검사에 대한 안내를 하는 부분의 코드이다.

 

그리고 당연히 email, password 입력받은 값도 useState로 상태관리!

로그인 / 회원가입 버튼을 클릭했을 때 동작하는 버튼 핸들러이다. 

왼쪽이 회원가입, 오른쪽이 로그인 로직이다. 

기본 로직은 fetch POST 요청 전송 -> API 참고하여 날아오는 response status에 따라 각각 다른 로직을 실행시켜주기.

성공 시 회원가입은 로그인 페이지로 리다이렉트, 로그인은 localStorage.setItem() 을 이용하여 response로 날아온 access token을 localStorage에 저장해준다. 그리고 todo로 페이지를 이동시켜준다. 

 

에러메세지 또한 API를 참고하여 더 친절하게 작성해주었다. 

 

여기서 겪은 몇가지의 Fetch API 관련 에러상황 및 허들이 있었다.

 

-> https://growingtangerine.tistory.com/79 로 Fetch API 와 Axios 의 차이에 대해 공부하고 기록해두었다. 

 

프론트엔드가 백엔드와 소통하는 법 (feat. Fetch API / Axios 비교)

프리온보딩 지원 과제로 todo 앱을 만들던 중, 기술에 대한 고민 없이 단순히 fetch 로 네트워크 요청을 보내게 되었다. 그러던 중, POST 요청의 body에 담아서 보내야 하는 데이터 타입이 헷갈렸고,

growingtangerine.tistory.com

 

1. fetch 와 axios의 차이점을 명확히 알지 못해서 fetch 요청 body에 어떤 형태로 데이터를 보내야 하는지 헷갈림. 

-> Fetch API는 직접 body에 보내는 데이터를 JSON.stringify()로 직렬화해주어야 한다. 

 

2. Fetch API에서 에러 핸들링 조건 분기를 어떻게 해야 하는지 명확히 알지 못해서 지저분한 코드를 작성함.

-> 백엔드 API 문서의 응답 코드를 보고 분기하기는 했으나, 조금 얼렁뚱땅 & 지저분한 감이 있다. 

-> Fetch API에서는 200번대를 넘어가도 reject 해주지 않아서, 직접 throw 로 에러 객체를 .catch 구문에 전달해주어야 한다. 

-> 로그인, 회원가입 모두 응답 객체의 ok 속성을 이용해서 에러 핸들링을 좀 더 범용적으로 리팩토링을 해볼 예정이다. (완료)

 

3. 에러 객체에 대한 이해 부족 -> .text(), JSON.parse()등 남용... 

-> 에러 객체 자체를 콘솔에 찍어보고, 필요없는 코드는 지우고 깔끔하게 동작하는 코드로 리팩토링 할 예정이다. (완료)

-> 에러 메세지를 errMsg에 담아서 alert 해주거나 조건문으로 확인하여 더 나은 UX를 가진 문구로 바꾸어 alert 해주었다. 이것보다 더 나은 코드가 있는지 좀 더 구글링 해 볼 예정이다.