gocamp - naver map api(2) / 지도 이벤트 등록

ryan·2022년 8월 15일
0
post-custom-banner

개요

  • 이번 프로젝트에서는 내가 보는 지도 위치정보를 기준으로 전국 야영장 데이터를 받아와야한다.

  • 그렇기 때문에, 지도의 위치나 zoom이 바뀔 때마다 실시간으로 이벤트 핸들링을 해줘서 지도의 상태를 myLocation이라는 전역 상태로 관리해줘야 했다.

    • 위치 정보뿐만 아니라 zoom도 필요한 이유는 이후에 설명할 마커 클러스터링에 활용한다.
  • 처음에는 touchend(위치 이동), mouseup(위치 이동) ,zoom_changed(줌 변경) 이벤트에 각각 리스너를 등록했다.
  • 이후, 위 모든 걸 한번에 관리하는 idle 이라는 이벤트를 발견했고, idle 이벤트를 활용해 지도 움직임이 발생할 때마다 myLocation state에 넣어주는 이벤트 핸들러를 등록했다.

  • 이벤트를 등록하는 방법은 매우 간단하다. naver.maps.Event.addListener를 통해 할 수 있으며, 매개변수로 이벤트 대상(map을 담아두고 있는 변수), eventname, 이벤트 리스너를 차례로 넣어주면 된다.

mapApis.jsx

  • map과 관련된 api는 최대한 분리하고 싶어서, mapApis라는 utils에 작성하고 export했다.
// 맵 상태 변경 이벤트
export const mapEventHanler = (naver, ref, set) => {
  const { map } = ref;
  let timer;

  // 이벤트 핸들러 디바운싱
  naver.maps.Event.addListener(map, "idle", () => {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      set({ lat: map.center._lat, lng: map.center._lng, zoom: map.zoom });
      console.log('event!!')
    }, 0);
  });
};

map.jsx

  • 분리한 mapEventHandler 함수에는 naver객체, map을 참조하는 변수, setState 함수를 매개변수로 넣어줬다.
import { mapEventHanler } from "../../utils/mapApi";
const { naver } = window;

const Map = () => {
  const [myLocation, setMyLocation] = useRecoilState(myLocationState);
  const mapRef = useRef({ map: null, markerList: [], marker: null });

  
  useEffect(() => {
    if (!myLocation.lat) return;
    if (mapRef.current.map === null) {
      // 맵 생성
      mapRef.current.map = new naver.maps.Map("map", {});
      
      // map event 등록
      mapEventHandler(naver, mapRef.current, setMyLocation);
    }
  }, [myLocation]);

결과

참고자료

profile
프론트엔드 개발자
post-custom-banner

0개의 댓글