본문 바로가기

Sparta x 이노베이션 캠프/팀 프로젝트

TIL : React 카카오 api 맵 예외처리, 카카오맵 중심좌표 이동시키기(Trouble Shooting, 코드리팩토링 ver.1)

반응형

실전 프로젝트 3주차. 벌써 반이나 지나갔다.

개발하고있는 어플리케이션은 여행후기공유 플랫폼이고 Minimum Viable Product (MVP)는 

1. 소셜로그인 (네이버, 카카오)

2. 회원가입시 여행관련 관심사 선택 => 추천페이지에서 관련 게시물 뜨게 만들어줌

3. 나의 게시물, 나의 관심 게시글, 나의 여행 일정 관리 (CRUD)

4. 게시글 full-text-search

5. 게시글 신고 -> 5번 이상 신고하면 삭제

6. 게시글 업로드 (editor, 지도) (CRUD)

7. 게시글 댓글 기능 (CRD)

8. 게시글 추천수, 좋아요, 최신 순, 태그 별 정렬

 

내가 맡은 기능은 1, 4, 5, 6, 7, 8(부분적) 번으로 오늘은 이 중 예외처리로 골머리를 앓은 지도에 대해 이야기 해보려 한다.

사용한 라이브러리: 카카오맵api를 직접 구현하는것보다 간편하게 개발 가능해서 선택하게 되었음.

 

맵 데이터

input 키워드 검색 -> 출발지 | 도착지 마커로 설정(선택)

-> 여행경로 그리기(선택) -> 여행코스저장을 누르면 데이터가 state에 저장되는 형식이다.

처음엔 마커가 있을 경우로 가정하여

center의 lat에 marker의  인덱스 0번에 해당하는 y, lng에는 x값을 넣어주었다. 문제는 유저가 폴리라인만 그렸을 경우, 맵을 아예 이용하지 않은 경우,  맵데이터가 전송되는 시간보다 함수의 실행이 빨라서 오류가 날 경우 오류메세지가 뜬다. 

 

오류가 날 수 있는 경우의 수

1. 마커가 없는경우

   a. 유저가 폴리라인만 이용

   b.맵 사용 안함

2. 맵 데이터 전송이 한 박자 느림

 

fetch로 상세페이지 데이터를 GET메소드로 컴포넌트에 직접 받아와서 state를 이용해서 polyline은 poly, marker는 center에 저장해줌. state에 마커와 폴리라인의 상세페이지의 좌표들이  잘 담기는것을 확인하고 맵의 center에 좌표가 들어 갈 수 있게 데이터를 입력해준다.

 

console.log(center?.length === 0 && poly[0]?.points.length !== 0); //폴리선택
console.log(poly[0]?.points[0]); //폴리만 선택 좌표
console.log(center?.length === 0 && poly.length === 0); //지도 선택 안할경우
console.log(center?.length !== 0); //마커만 찍은 경우
console.log(center === undefined || poly === undefined); // 데이터 늦게 들어올때

 

위과 같은 조건식을 세워보고 오류가 날 때 대입해서 true인 것을 골라내서 삼항연산자를 이용해 맵 컴포넌트에 적용해줌 .

아래는 맵이 렌더링되는 부분의 코드.

 

<div className="map-wrapper">
            {center?.length === 0 && poly.length === 0 ? ( //맵선택안함
              <> {detail.nickname}님은 경로를 공유하지 않았습니다. </>
            ) : center === undefined || poly === undefined ? ( //오류방지
              <Map // 로드뷰를 표시할 Container
                center={{
                  lat: 37.566826,
                  lng: 126.9786567,
                }}
                style={{
                  width: "100%",
                  height: "300px",
                }}
                level={5}
              >
                {overlayData.polyline.map(({ points, options }, i) => (
                  <Polyline key={i} path={pointsToPath(points)} {...options} />
                ))}

                {overlayData.marker.map(({ x, y, zIndex }, i) => (
                  <MapMarker
                    key={i}
                    position={{
                      lat: y,
                      lng: x,
                    }}
                    zIndex={zIndex}
                  />
                ))}
              </Map>
            ) : center?.length === 0 && poly[0]?.points.length !== 0 ? ( //폴리만 선택
              <Map
                center={{
                  lat: poly[0]?.points[0].y,
                  lng: poly[0]?.points[0].x,
                }}
                style={{
                  width: "100%",
                  height: "300px",
                }}
                level={4}
              >
                {overlayData.polyline.map(({ points, options }, i) => (
                  <Polyline key={i} path={pointsToPath(points)} {...options} />
                ))}

                {overlayData.marker.map(({ x, y, zIndex }, i) => (
                  <MapMarker
                    key={i}
                    position={{
                      lat: y,
                      lng: x,
                    }}
                    zIndex={zIndex}
                  />
                ))}
              </Map>
            ) : (
              //마커있을때
              <Map
                center={{
                  lat: center[0]?.y || "",
                  lng: center[0]?.x || "",
                }}
                style={{
                  width: "100%",
                  height: "300px",
                }}
                level={3}
              >
                {overlayData.polyline.map(({ points, options }, i) => (
                  <Polyline key={i} path={pointsToPath(points)} {...options} />
                ))}

                {overlayData.marker.map(({ x, y, zIndex }, i) => (
                  <MapMarker
                    key={i}
                    position={{
                      lat: y,
                      lng: x,
                    }}
                    zIndex={zIndex}
                  />
                ))}
              </Map>
            )}
          </div>

 

이렇게 조건부 렌더링을 해주니 더이상 맵에서 오류가 나서 흰 화면이 나타나 내 머리도 백지가 되어버리는 일은 아직까지 없으나 

커밋 푸시하고 조원분들이랑 기능들을 develope branch에 merge 한 후 다른 문제를 발견함.....

게시글 상세조회를 하고 글쓰기 버튼을 눌러 AddPost 페이지로 이동하면 게시글 상세조회를 했던 페이지의 맵 데이터가 추가하지도 않은 지도에 남아있어서 새로고침을 해 주어야 날아가는 것을 발견했다. 없던 버그가 갑자기 생겨서 예전 버전이랑 현재 코드랑 비교를 해보니 달라진게 거의 없다. 로그 찍어본 것만 달라짐. 봐도 봐도 이유를 모르겠어서 이유를 더 고민을 해 보아야 할 것 같다.

 

####

 

라이브러리에 지도 범위 재설정 하기라는 샘플이 있는데 마커만 그릴 경우 코드량도 짧아지고 좋다고 다른 조원분의 추천을 받아서 처음에는 기존의 코드를 수정 해 봤다. 오류는 나지 않았지만 useMemo에서 의존성배열에 뭘 추가해도 지도 중심 이동이 안되었슴. 사용법을 제대로 숙지 하지 않고 사용한 이유 인 듯. 나중에 다시 수정 해봐야겠다. 

 

이어지는글 - 리팩토링 ver.2

 

References

 

 

[React] Router v6 리다이렉트 및 경로 이동 처리(새로고침X): 404에러 페이지 렌더링 활용

# React-Router-Dom V6 리다이렉션 및 경로이동 처리 방법 일반 자바스크립트에서는 window.location 을 이용해 특정 경로로 이동시킬 수 있다. 리액트에서도 물론 이용 가능하지만, 페이지가 새로고침되

curryyou.tistory.com

 

반응형