Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- MUI
- kakao map api
- 정규표현식
- sort
- 페이지네이션
- 코드스테이츠 메인프로젝트
- 알고리즘
- JavaScript Deep Dive
- OSI 7계층
- input class
- 재귀함수
- primitive type
- 버블정렬
- javascript
- 코드스테이츠
- 백준
- Node js
- 코딩테스트
- nodejs
- 프론트엔드
- 백준 nodeJS
- CSS
- 배열
- 유데미
- 자바스크립트
- 이벤트 루프
- 자료구조
- Native select
- next/Image
- react js
Archives
- Today
- Total
신입 개발자에서 시니어 개발자가 되기까지
[메인 프로젝트] kakao map api 리팩토링하기(feat. 함수 추출하기) 본문
마커 클러스터링을 브로깅하면서 setMarkerCluster 함수가 너무 길어서 리팩토링을 하기로 마음 먹었다.
리팩토링 방법은 진우님께서 추천해주신 리팩토링 6장에 있는 함수 추출하기다.
지도 생성함수 추출하기
여러 함수에서 카카오 지도를 생성하고 있었기 때문에 반복되는 코드를 함수로 만들어서 재사용 했다.
const generateKakaoMap = (center: getMapAndMarkerPropsType['center']) => {
let mapContainer =
document.getElementById('map') || document.createElement('div'), // 지도를 표시할 div
mapOption = {
center: new kakao.maps.LatLng(center.lat, center.lng), // 지도의 중심좌표
level: 5, // 지도의 확대 레벨
};
return new kakao.maps.Map(mapContainer, mapOption);
};
이렇게 추출한 후
const map = generateKakaoMap(coords);
이렇게 썼다.
커스텀 오버레이 생성 코드 함수 추출하기
커스텀 오버레이를 생성하고, 이벤트를 바인딩 해주는 코드가 상당히 길고 따로 추출할 수 있을 것 같아서 이렇게 추출했다.
다만, 여기 안에 있는 이벤트를 바인딩하는 함수는 추출하기 어렵다.
isOverlayOpen이라는 변수를 캡슐화해서 사용하기 때문이다. 각각의 마커들에 이벤트를 바인딩 해주고, 이 변수를 함수 내에서 참조하고 있다.
마커를 하나 클릭할 때마다 true / false로 변경하고 true면 커스텀 오버레이를 보여주는 방식이기 때문에, 각각의 마커에는 각각의 isOverlayOpen 이라는 상태가 존재해야 한다.
그런 맥락에서 openAllOverlayButton은 marker처럼 여러 개가 있는 게 아니고 지도위에 있는 모든 게시물을 볼 수 있게 만들어주는 버튼인데 이 버튼을 굳이 반복문을 돌리면서 event를 바인딩 해주는 것도 위에서 기술한 이유 때문이다.
const setCustomOverlay = (
sharingLists: kakaoMapItemType[],
markers: any[],
map: any
) => {
for (let i = 0; i < sharingLists?.length; i++) {
const openAllOverlayButton = document.getElementById('openAllOverlay');
... 중략
let isOverlayOpen = false;
... 중략
kakao.maps.event.addListener(sharingItemMarker, 'click', function () {
if (!isOverlayOpen) {
customOverlay.setMap(map);
isOverlayOpen = true;
} else if (isOverlayOpen) {
customOverlay.setMap(null);
isOverlayOpen = false;
}
});
openAllOverlayButton?.addEventListener('click', function () {
if (!isOverlayOpen) {
customOverlay.setMap(map);
isOverlayOpen = true;
} else if (isOverlayOpen) {
customOverlay.setMap(null);
isOverlayOpen = false;
}
});
};
이 함수를 setMarkerCluster 함수 내에서 호출한다.
setCustomOverlay(sharingLists, markers, map);
리팩토링 후
export const setMarkerCluster = async (
coords: getMapAndMarkerPropsType['center'],
sharingLists: kakaoMapItemType[],
setMapCenter: getMapAndMarkerPropsType['setTargetCoord'],
setIsMapLoading: React.Dispatch<React.SetStateAction<boolean>>
) => {
const map = generateKakaoMap(coords);
let marker = new kakao.maps.Marker({ position: map.getCenter() }); // 클릭한 위치를 표시할 마커입니다
marker.setMap(map);
marker.setTitle('지도 중심');
// 마커 클러스터러를 생성합니다
const clusterer = new kakao.maps.MarkerClusterer({
map: map, // 마커들을 클러스터로 관리하고 표시할 지도 객체
averageCenter: true, // 클러스터에 포함된 마커들의 평균 위치를 클러스터 마커 위치로 설정
minLevel: 5, // 클러스터 할 최소 지도 레벨
});
const zoomControl = new kakao.maps.ZoomControl();
map.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);
//Kakao maps에서 제공하는 marker를 담을 배열
let markers: any[] = [];
let mapLevel: number;
kakao.maps.event.addListener(map, 'dragend', function () {
let latlng: any = map.getCenter();
// latlng가 any가 아닐 때 Ma와 La 필드가 latlng에 존재하지 않는다고 오류뜸.
const mapCenter = { lat: latlng.Ma, lng: latlng.La };
marker.setPosition(new kakao.maps.LatLng(mapCenter.lat, mapCenter.lng));
setDefaultCoordsAndAddress(mapCenter, (result, status) => {
if (status === kakao.maps.services.Status.OK) {
let detailAddr = !!result[0].address.address_name
? result[0].address.address_name
: result[0].road_address.address_name;
setMapCenter((prev: any) => {
return { ...prev, ...mapCenter, address: detailAddr };
});
}
});
});
setCustomOverlay(sharingLists, markers, map);
clusterer.addMarkers(markers);
setIsMapLoading(false);
};
'코드스테이츠' 카테고리의 다른 글
[메인프로젝트] 스토리북 버전 7 command not found (1) | 2023.04.17 |
---|---|
[메인 프로젝트] 웹사이트 최적화 (feat. lighthouse) (0) | 2023.03.19 |
[메인프로젝트] 지도 기능(마커 클러스터) - 내 주변 페이지(feat. kakao map) (3) | 2023.03.03 |
[메인 프로젝트] 메인프로젝트 - 위치검색 기능/검색 페이지(feat. 카카오 맵) (3) | 2023.02.21 |
[메인 프로젝트] 메인프로젝트 회고 - 디자인 패턴(feat. atomic) (5) | 2023.02.14 |