127일차 TIL : 최종프로젝트 - 지도 범위 재설정

변시윤·2023년 3월 6일
0

내일배움캠프 4기

목록 보기
129/131
post-custom-banner

오늘 구현한 내용

  • 지도 범위 재설정
  • 게시글 수정시 메모 미반환 및 미반영 버그 해결
  • 지도 및 코스 CRUD 커스텀훅 제작
  • 지도 및 코스 컴포넌트 재사용

지도 범위 재설정

문제 상황

현재는 움짤과 같이 여행지를 클릭할 때마다 지도 사이즈가 일정하지 않고 불규칙적으로 확대 or 축소가 되고 있다.

검색 실행시 검색결과에 해당하는 지도 범위(bounds)를 DB에 저장해서 여행지를 선택할 때마다 해당 bounds를 보여주는 방식인데 bounds는 검색 결과를 기반으로 설정되기 때문에 이런 이슈가 발생했다.

예를 들어서 첫 번째 여행지는 서울로 검색한 다음 롯데월드를 선택하고, 두 번째 여행지는 송파구로 검색한 후 석촌호수를 선택했다고 가정해보자. 이 경우 첫 번째 여행지는 서울시 전체에 대한 bounds를 저장하고, 두 번째 여행지는 송파구에 대한 bounds만 저장한다. 결국 같은 지역임에도 불구하고 첫 번째 여행지를 클릭시 서울시 지도가, 두 번째 여행지를 클릭시 송파구 지도로 설정되는 것이다.

해결

💡 bounds 대신 position 사용하기

Before

  useEffect(() => {
    if (map !== undefined) {
      // @ts-ignore
      map.panTo(boundsInfo);
    }
  }, [filteredIdx]);
  
    return (
    <div className="w-full flex h-full mb-20 xs:mb-6">
      <Map
        center={{
          lat: 37.566826,
          lng: 126.9786567,
        }}
        level={5}
        // @ts-ignore
        onCreate={setMap}
      >
    </div>
  );

filteredIdx는 각각의 여행지의 인덱스 값이다. 기존에는 여행지를 클릭할 때마다 useEffect로 지도 범위를 재설정해주는 방식이었다.

After

      <Map
        center={{
          lat:
            filteredIdx === "" || filteredIdx === -1
              ? 37.566826
              : lists[filteredIdx]?.position.lat,
          lng:
            filteredIdx === "" || filteredIdx === -1
              ? 126.9786567
              : lists[filteredIdx].position.lng,
        }}
        level={4}
      >

postion은 카카오맵 API에서 제공하는 위도와 경도를 합산한 정보다. 이 정보를 활용해서 여행지를 클릭할 때마다 해당 여행지의 위도 경보로 재설정하도록 구현했다. 단, 이 경우 이전처럼 지도가 부드럽게 전환되는 효과는 사용할 수 없다. 해당효과는 카카오맵에서 제공하는 panTo 메서드에서만 가능하다.

예외 처리

  • 최초 렌더링시
    최초 렌더링시에는 선택한 여행지가 없다. 즉, filteredIdx값이 없기 때문에 최초 렌더링시 디폴트로 보여줄 좌표를 설정한다.
  • 마지막 여행지 삭제시
    3개의 여행지로 구성된 코스가 있다고 가정해보자. 여기서 마지막 여행지를 삭제하면 lists는 0번 째와 1번 째 요소만을 갖게 되지만, filteredIdx는 여전히 2에 머무른다. 즉, lists[2]가 없으므로 에러가 발생한다.

          deleteCourse: (state: any, action) => {
            state.courseList = [...current(state).courseList];
            state.courseList.splice(action.payload, 1);
            if (state.filteredIdx > state.courseList.length - 2) {
              state.filteredIdx = state.courseList.length - 1;
            }
          },

    마지막 여행지 삭제시에는 filteredIdxlists의 마지막 요소를 가리키도록 예외 처리를 해주었다. 모든 여행지 삭제시 filteredIdx의 값이 -1이 되는데 이 경우에도 디폴트 좌표를 보여주도록 설정했다.

  • 수정페이지

          <Map
            center={{
              lat:
                filteredIdx === ""
                  ? lists[0]?.position.lat
                  : filteredIdx === -1
                  ? 37.566826
                  : lists[filteredIdx]?.position.lat,
              lng:
                filteredIdx === ""
                  ? lists[0]?.position.lng
                  : filteredIdx === -1
                  ? 126.9786567
                  : lists[filteredIdx].position.lng,
            }}

    수정페이지의 경우 이미 코스 정보가 존재하므로 최초 렌더링시에는 첫 번째 코스의 좌표를 반환하도록 설정했다.

profile
개그우먼(개발을 그은성으로 하는 우먼)
post-custom-banner

0개의 댓글