Iroom 클론 프로젝트 기록

✔️ 작업 기간

  • 2021.11.05~2021.11.26

✔️ 팀원 구성

  • Front-end(3명) : 공은배, 서지수, 조은

✔️ 깃허브 주소

GitHub - jseo9732/iroom-clone: 모임공간이룸 클론코딩 - https://www.iroomstudy.com/

모임공간이룸 클론코딩 - https://www.iroomstudy.com/. Contribute to jseo9732/iroom-clone development by creating an account on GitHub.

github.com

✔️ 사용 기술 스택

  • HTML, CSS
  • React, React Hooks, React Router
  • JavaScript (ES6)
  • Firebase (Back-end)
  • GitHub

✔️ 파트별 기능 구현

  • 메인 페이지 (Main)
  • Navigation component
  • Footer component
  • Router
  • 소개 페이지 (Introduction)
  • 예약 페이지 (Reservation)
  • 마이 페이지 (Profile)
  • 로그인 페이지 (Login)
  • 회원가입 및 로그인

✔️ 나의 작업 부분

예약신청 및 마이페이지에서 확인, 취소기능
  • 예약 페이지(Reservation)
  • 예약 모달창 구현
  • 예약 정보 전송 (→Firebase)
  • 마이 페이지(Profile)
  • 마이페이지 레이아웃 구현
  • 예약 정보 표시 및 삭제기능 구현

✔️ 작업 기록 (예약 페이지)

모달창 구현

export default function Reservation({userObj, isLoggedIn}) { const [IsopenReserveModal, setIsOpenReserveModal] = useState(false); const toggleReserveModal = () => { setIsOpenReserveModal((prev) => !prev) } ... { openReserveModal && <ReserveModal toggleReserveModal={toggleReserveModal} /> }
  • 예약하기 버튼을 눌렀을 때 toggleReserveModal 함수를 실행하여 useState의 현재 상태를 true로 바꾸고, 값이 true일 때 ReserveModal 컴포넌트를 띄우는 방식으로 모달창 띄우기를 구현하였다.
  • 또한 상태를 바꾸는 함수를 ReserveModal 컴포넌트로 줘서 모달 창에서 닫기 버튼을 눌렀을 때 이 함수를 실행하는 방식으로 모달창 닫기를 구현하였다.

useNavigate 이용해 Redirect 구현

 const navigate = useNavigate(); const redirectLogin = () => { window.alert("로그인 후 이용해주세요"); navigate('/login'); }
{ openReserveModal && ( isLoggedIn ? <ReserveModal uid={userObj.uid} username={userObj.displayName} isLoggedIn={isLoggedIn} toggleReserveModal={toggleReserveModal} /> : redirectLogin()) }


Firebase로 데이터 전송

const {phoneNum, room, reserveDate, reserveTime, reserveRemainTime} = reserveInputs; const onReserveSubmit = async (e) => { e.preventDefault(); const reserveObj = { ...reserveInputs, createdAt: Date.now(), userId: uid, } if (phoneNum && room && reserveDate && reserveTime && reserveRemainTime) { const ok = window.confirm("위의 정보로 예약하시겠습니까?"); if(ok) { try { await setDoc(doc(dbService, "reservations", `${reserveObj.createdAt}`), reserveObj); } catch (e) { console.error("Error adding document: ", e); } setReserveInputs({ phoneNum: "", room: "", reserveDate: "", reseveTime: "", reserveRemainTime: "", }) toggleReserveModal(); window.alert("예약되었습니다"); } } else { window.alert("정보를 전부 입력해주세요"); } }

✔️ 문제 해결

여러개의 input 통합하여 관리하기

const [phoneNum, setPhoneNum] = useState(""); const [room, setRoom] = useState(""); const [reserveDate, setReserveDate] = useState(""); const [reserveTime, setReserveTime] = useState(""); const [reserveRemainTime, setReserveRemainTime] = useState(""); const onPhoneNumChange = (e) => { const { target : { value } } = e setPhoneNum(value); } const onRoomChange = (e) => { const { target : { value } } = e setRoom(value); } const onReserveDateChange = (e) => { const { target : { value } } = e setReserveDate(value); } const onReserveTimeChange = (e) => { const { target : { value } } = e setReserveTime(value); } const onReserveRemainTimeChange = (e) => { const { target : { value } } = e setReserveRemainTime(value); }
const [reserveInputs, setReserveInputs] = useState({ phoneNum: "", room: "", reserveDate: "", reseveTime: "", reserveRemainTime: "", }); const onReserveChange = (e) => { const { target : { value, name }} = e setReserveInputs({ ...reserveInputs, [name] : value }) }
  • 예약하기에서 예약 정보를 받을 때 정보들을 input과 select값 여러개로 받게되어 useState를 각각의 값마다 작성하였다.
  • 하지만 이렇게 작성하니 코드도 길어지고, 가독성이 떨지는 문제점이 생겼다.
  • 이를 useState에 받은 전체 값들을 객체로 저장하였고, 값이 변경되었을 때 spread문법을 이용하여 저장하는 방식으로 코드를 고쳐서 개선하였다.

✔️ 프로젝트 후기

리액트 스터디를 다 진행하고, 스터디 팀원들이 다 프론트쪽이라 백엔드를 따로 구하기는 애매해서 파이어베이스를 사용하여 프로젝트를 진행하기로 하였고, 이를 위해 노마드코더의 트위터 클론코딩 강의를 스터디원들끼리 각 파트를 분배하여 정리하며 공부하였다. 강의정리를 마친 후 3명이서 모임공간이룸 홈페이지 클론을 진행하였는데, 이 사이트에서 예약은 네이버예약으로 받았기에 우리가 예약 기능과 로그인 기능, 예약 정보를 볼수있는 마이페이지를 추가하였다. 그중 나는 예약페이지랑 마이페이지의 기능 구현을 맡았고 이를 구현하기 위해 모달창 생성, Firebase로 데이터 전송 및 불러오기, 불러온 데이터 표시 등 다양한 작업을 할 수 있었다.

느낀 점

  • 어떤 프로젝트를 진행하며 협업을 하는것이 처음이라 시작할 때는 막연함에서 온 무서움(내가 깃허브에 커밋을 잘못해서 꼬여버리면 어떡하지? 와 같은..) 도 있었지만 프로젝트를 진행해보니 별거 아닌 걱정이었다. 일단 시작해봐야 배울점이 많다는것을 깨달았다.
  • 또 슬랙과 깃허브를 이번 기회에 처음 사용해보았다. 특히 깃허브를 사용하여 프로젝트를 관리하는것이 어색하고 잘 사용할 수 있을지 걱정했는데, 계속 커밋, 풀, 푸시 등을 이용하여 사용하니까 이 과정들이 익숙해졌고 깃을 이용해 버전관리를 하는 전체적인 흐름을 어느정도 이해하게 되었다.
  • Firebase를 이용하여 프로젝트를 진행하면서 NoSQL기반의 데이터베이스 구조에 대해 조금 더 공부할 수 있었고, 공식문서가 잘 나와있어서 문서를 읽어가며 공부하였고, 공식문서를 읽는 것도 조금은 더 익숙해진거같다. 그런데 Firebase를 이용하면 코드가 간결하고 작업이 줄어서 좋긴 했지만, SQL을 사용한 db를 연결하여 작업을 해보고 싶은 아쉬움도 있었다.
  • 이번 프로젝트를 진행하며 아직 많이 부족하고 배워야할 부분도 많다는 것을 절실히 깨달았고, 다음에는 백엔드 개발자도 포함된 더 큰 규모의 프로젝트 진행해보고 싶고, TypeScript 언어나 Redux 사용법도 배워서 이를 이용한 프로젝트도 해 봐야겠다고 생각했다.