이번 프로젝트에서는 내가 보는 지도 위치정보를 기준으로 전국 야영장 데이터를 받아와야한다.
그렇기 때문에, 지도의 위치나 zoom이 바뀔 때마다 실시간으로 이벤트 핸들링을 해줘서 지도의 상태를 myLocation이라는 전역 상태로 관리해줘야 했다.
마커 클러스터링
에 활용한다. touchend
(위치 이동), mouseup
(위치 이동) ,zoom_changed
(줌 변경) 이벤트에 각각 리스너를 등록했다.idle
이라는 이벤트를 발견했고, idle
이벤트를 활용해 지도 움직임이 발생할 때마다 myLocation state에 넣어주는 이벤트 핸들러를 등록했다. naver.maps.Event.addListener
를 통해 할 수 있으며, 매개변수로 이벤트 대상(map을 담아두고 있는 변수), eventname, 이벤트 리스너를 차례로 넣어주면 된다. // 맵 상태 변경 이벤트
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);
});
};
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]);