Salangdung_i의 기록
[ 팀 프로젝트 ] 호텔 예약 사이트 과제 후기 본문
마지막 프로젝트 회고
원티드 프리온보딩 프론트엔트 코스에서 마지막으로 진행한 호텔 예약 사이트 과제 후기이다. 8월 1일부터 5일까지 5일간 트립비토즈의 기업과제를 만들어 보았다.
마지막 프로젝트인 만큼 그동안 해보지 못한 부분을 개발하고 싶었다. 나는 그동안 UI 작업, 기능 구현, 레이아웃, 라우터 작업들을 해보았다. 이전 프로젝트 들에서 통신 쪽을 맡아 개발하는 팀원이 그동안 리액트 쿼리를 써서 구현하였고, 본인이 공부할 때 참고했던 공식문서와 유튜브 영상을 공유해주었다.
이 유튜브 영상을 보면서 react query에 관심이 생겼다. 개발 경험이 있지만 fetching, caching용어와는 친숙하지 않았고, fetch는 axios를 공부할때 살짝 들어본 정도였다.
결과적으로 이번 프로젝트에서 내가 맡은 역할은
- Json server
- 통신 작업
- 서버 분리
- React query
- 전체 조회
- 예약 확인
- 무한 스크롤 기능 구현
이다.
작업 순서를 json server 구현 -> react query (전체 조회 -> 예약 확인 -> 무한 스크롤) 으로 잡고 react query 작업의 경우 기능을 완성할 때마다 PR을 올려 팀원들에게 공유하려고 했다. 이전 프로젝트에서 통신 작업이 전부 완성되고 마지막에 붙이는 경우가 있었는데 이때 데이터가 제대로 불러와지지 않거나 생각지도 못한 오류가 발생해 에러 잡는데 시간이 많이 걸렸기 때문에 작업을 세분화해 팀원들과 공유해야겠다고 생각했다.
작업을 하면서 발생 했던 문제, 해결 과정
1. json data 고민 🤔
기존 제공된 json data 형식은 아래와 같았다.
{
"hotel_name": "에코랜드 호텔",
"occupancy": {
"base": 2,
"max": 3
}
}
메인 페이지에 검색한 결과를 뿌려줄 때 검색에 들어갈 데이터는 1. 숙소 이름 2. 날짜 3. 최대 인원이다. 날짜는 json data에 없어 고려하지 않았고, get 요청을 보내 object안에 data에 접근하는 방법을 찾지 못해 json data 형식을 바꾸었다.
{
"hotelName": "에코랜드 호텔",
"base": 2,
"max": 3,
"reservation": false,
"id": 1
}
occupancy 밖으로 base, max를 꺼내고, 추후 예약 완료 기능을 구현하기 위해 id와 reservation 항목을 추가하였다. json server github를 참고하여 get 요청을 보낼 때 아래와 같이 사용하였다.
http://localhost:8000/hotels?hotelName_like=${payload.hotelName}&max_gte=${payload.max}
예약을 처리하는 과정에서 팀원들과 고민을 많이 나누었다. 욕심으로는 예약을 관리하는 json을 하나 더 만들어 예약상태(예약 시작 날짜, 끝 날짜, 인원)가 들어가는 기능을 따로 구현하는 것이 더 완성도 높지 않을까? 또, 열심히 달력 검색 기능을 구현하였는데 데이터에는 날짜가 없어서 써먹지 못헤서 아쉽다. 이런 고민들을 나누었는데 프로젝트 기간은 5일로 짧고 그 시간 안에 완성해서 발표까지 해야 돼서 빠듯했다. 기업과제의 필수 구현 사항에는 예약 데이터는 로컬 스토리지로 관리로 명시되어있어서 논의 끝에 필수 구현에만 집중하기로 했다.
2. 서버 분리
서버 요청을 보낼 때마다 새로고침이 발생하는 문제가 있었다. 이전 프로젝트에서 이런 오류가 발생했을 때 아래의 과정을 통해 트러블 슈팅한 경험이 있어 이번에도 프로젝트 외부로 json-server 분리하여 해결했다.
- axios ⇒ 빌트인 fetch 기능을 써도 동일하게 발생 (x)
- react-query ⇒ 이전 프로젝트의 캐시 기능 시연할 때 이미 검증 (x)
- server.js ⇒ 순정 json-server 사용해도 동일하게 발생 (x)
- json-server ⇒ 프로젝트 외부로 분리하니 문제 해결
3. 검색 payload 변경 시 API 호출 오류
메인 페이지에서 검색의 데이터를 getInfiniteScroll에 넘겨준다.
getInfiniteScroll 함수에서는 useInfiniteQuery의 key값에 넘겨받은 payload의 값을 넣어준다.
이렇게 처리한 이유는 React Query는 쿼리 키를 기반으로 쿼리 캐싱을 관리하기 때문이다. 따라서 payload의 hotelName, max값이 변경될 때마다 React Query가 자동으로 refetcing 한다. (참고 react query)
4. infinite scroll 에러
무한 스크롤 구현 시 react Intersection Observer를 사용하였는데 , 이건 대상이 화면에 보이면 callback 함수를 실행하여 원하는 동작을 수행할 수 있도록 타깃을 감시하는 역할을 한다. 무한 스크롤 구현은 오류는 검색 데이터가 없을 때나 불러온 데이터가 10보다 적을 때도 계속 API 호출이 발생했다.😢
에러 처리 1
inView의 값이 true일 때 hasNextPage 값도 true일 때만 fetchNexPage 함수를 호출하도록 처리하였다. fetchNexPage는 다음 페이지를 불러오는 기능을 한다. hasNextPage는 useInfinteQuery의 getNextPageParam과 관련이 있는데 이 옵션은 불러올 데이터가 더 있는지 여부와 fetch 할 정보를 결정할 때 사용한다. getNextPageParam 함수가 undefined 말고 다른 값을 반환하면 hasNextPage는 true가 된다. 따라서 메인 페이지 하단의 ref가 감지되어 inView값이 true가 되고, useInfinteQuery의 getNextPageParam 함수에서도 pageParam과 data를 전달해 주었을 때 무한 스크롤이 작동한다.
에러 처리 2
불러온 데이터가 10보다 적을 때도 계속 API 호출되었고 이를 해결하기 위해 res.length의 값이 10보다 작으면
return { data: res, pageParam: undefined };
위의 코드를 반환하도록 하였는데, 이 이유는 응답 값이 10보다 작으면 infiintequey가 지속 호출되는 것을 막기 위해 작성하였다. 또 옵션에 refetchOnWindowFocus를 사용하였는데 refetchOnWindowFocus는 데이터가 stale 상태일 경우 윈도 포커싱 될 때마다 refetch를 실행하는 옵션입니다. 포커싱 될 때 refetch를 방지하기 위해 사용하였다.
후기
그동안 궁금했던 react query를 써볼 수 있어서 개인적으로는 만족스러운 프로젝트였다. 특히 리액트 쿼리의 키값이 변경되었을 때 refehing이 알아서 일어나는 것은 너무나 편리하다.👍 그리고 마지막 프로젝트의 발표를 맡게 되었는데 하필 발표 순서도 7개의 팀 중에서 마지막이었다. 4시간 동안의 세션이고 마지막이어서 집중도가 떨어졌을 줄 알았는데 query key 코드나, stale 상태가 무엇인지 질문하고 열심히 들어주셔서 발표를 준비한 시간이 뿌듯하고 다른 분들께 감사했다. 아쉬운 점은 프로젝트 기간과 json 서버를 사용한 것이었는데 5일이 아니라 2주의 기간이었다면 우리 팀에서 넣고 싶었던 기능(예약 json을 분리해서 따로 관리, 날짜 데이터를 사용한 검색을 구현, 예약 취소 정책들을 만들어 실제 서비스와 유사하게 구현)을 구현하여 좀 더 완성도 있는 프로젝트가 되지 않았을까 생각한다.
'개발 > 2022_회고' 카테고리의 다른 글
[ 팀 프로젝트 ] 수업 일정 페이지 과제 후기 (2) | 2022.08.14 |
---|---|
Wanted | 프리온보딩 프론트엔드 코스 [ 5주차 | 주간회고 ] (0) | 2022.08.07 |
Wanted | 프리온보딩 프론트엔드 코스 [ 4주차 | 주간회고 ] (0) | 2022.07.31 |
Wanted | 프리온보딩 프론트엔드 코스 [ 3주차 | 주간회고 ] (0) | 2022.07.24 |
Wanted | 프리온보딩 프론트엔드 코스 [ 2주차 | 주간회고 ] (0) | 2022.07.17 |