[React] Hook으로 카카오맵 API 사용하기 | 마커 표시, 커스텀 오버레이
📍카카오맵 API 키 발급받기
업체의 장소를 표현하기 위해 카카오맵 API를 사용하였다. https://developers.kakao.com로 접속해서 로그인을 하고 애플리케이션 추가하기 버튼으로 앱 키를 발급 받는다. 네이티브 앱 키, REST API 키, Admin 키, JavaScript 키 중에서 JavaScript 키를 이용한다.
📍도메인 등록하기
내 애플리케이션 > 앱 설정 > 플랫폼에서 구현하려는 운영체제에 맞게 플랫폼 등록을 한다. 리액트를 이용하여 웹 사이트 화면에 지도를 띄우려고 했기 때문에 Web 플랫폼에 등록을 했다. 그 도메인에서만 API를 사용할 수 있기 때문에 꼭 등록해줄 것! (최대 10개까지 가능)
📍카카오맵 API 문서 훑어보기 https://apis.map.kakao.com/
왼쪽에 위치한 네비게이션에서 'Guide' 항목을 링크하여 들어가면 어떤 순서대로 지도를 구현할 수 있는 지 상세하게 설명되어 있다. 다만 HTML + JavaScript 조합으로 문서가 설명되어 있어서 리액트 훅으로 구현하기 위해 구글링을 했다. 친절하게 이미 포스팅을 해 놓으신 분들이 많음!
📍스크립트 코드 index.html에 넣기
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY를 넣으시면 됩니다."></script>
해당 코드를 public > index.html head 부분에 넣는다. 다른 분들의 포스팅을 보다가 body에 넣으시는 분들도 봤는데 해당 가이드에서도 'API를 로딩하는 스크립트 태그는 HTML파일안의 head, body 등 어떠한 위치에 넣어도 상관없습니다. 하지만, 반드시 실행 코드보다 먼저 선언되어야 합니다.'라고 언급되어 있어서 크게 상관되는 부분은 아닌 것 같고 지도가 먼저 로딩 되었으면 싶어서 헤드에 넣었다.
📍Map 컴포넌트 만들기
지도 자체를 컴포넌트로 만들어서 사용할 생각으로 Map.js라는 파일을 하나 생성한다.
// src > components > Map.js
import React from 'react';
const Map = () => {
return (
<div id="map"></div>
);
};
export default Map;
📍useRef 사용하기
import React, { useRef } from 'react';
const Map = () => {
const mapContainer = useRef(null);
return (
<div
id="map"
ref={mapContainer}
style={{ width: '100%', height: '350px', display: 'block' }}
></div>
);
};
export default Map;
document.getElementById를 사용해서 구현하는 분들도 봤지만 리액트 방식으로 구현하는 동작은 아닌 거 같아서 포스팅을 찾아보니 'useRef'을 사용해서 구현한 분의 포스팅을 참고했다. 지도를 띄울 <div>안에 ref 속성을 사용해서 이를 참조할 수 있도록 값을 넣어준다.
📍useEffect를 이용하여 지도 띄우기
import React, { useEffect, useRef } from 'react';
const Map = () => {
const mapContainer = useRef(null);
const { kakao } = window;
const position = new kakao.maps.LatLng(원하는 위도 값, 원하는 경도 값);
const mapOptions = {
center: position, // 지도의 중심좌표
level: 4 // 지도의 확대 레벨
};
useEffect(() => {
const map = new kakao.maps.Map(mapContainer.current, mapOptions);
});
return (
<div
id="map"
ref={mapContainer}
style={{ width: '100%', height: '350px', display: 'block' }}
></div>
);
};
export default Map;
const { kakao } = window;
해당 코드를 작성해줘야 브라우저에 지도를 보여줄 수 있다. window 없이 kakao만 작성하면 브라우저는 kakao가 무엇인지 모르기 때문에 에러를 뱉어낸다. 'position'에 표시하고 싶은 지도의 위치를 위도, 경도 값을 찾아 보여준다. 주소를 입력하면 위도와 경도로 변환해주는 사이트를 이용하였다. Dawul 주소 변환서비스
const map = new kakao.maps.Map(mapContainer.current, mapOptions);
그리고 카카오맵을 불러오며 지도를 넣을 위치와 옵션을 인자를 넘겨줄 때, 첫번째 인자에 .current를 꼭 붙여줄 것. 참조 값을 사용해서 그런지 .current를 붙여주지 않으면 브라우저에 지도가 표시되지 않고 에러가 뜨면서 아무것도 보이지 않는다.
📍마커와 커스텀오버레이 표시
useEffect(() => {
const map = new kakao.maps.Map(mapContainer.current, mapOptions);
const marker = new kakao.maps.Marker({ position }); // 마커 생성
// 커스텀 오버레이에 표출될 내용
const content = `
<div class="customoverlay">
<span>포썸</span>
</div>`;
// 커스텀 오버레이 생성
new kakao.maps.CustomOverlay({
map,
position,
content
});
// 마커가 지도 위에 표시되도록 설정
marker.setMap(map);
}, []);
const position = new kakao.maps.LatLng(원하는 위도 값, 원하는 경도 값);
같은 포지션 값을 마커, 커스텀 오버레이에 써야해서 변수로 지정해서 이를 재사용했다.
📍결과
스타일링을 입히면 다음과 같이 카카오맵 위에 마커와 커스텀 오버레이가 생성된다.
프로젝트를 하면서 업체의 위치를 표시하기 위해 처음으로 카카오맵 API를 사용해봤다. 전에 자바스크립트 강의 들을 때 Leaflet을 이용해서 지도 API를 사용해본 적이 있는데 그 때랑 구현하는 방식은 비슷하다. 두 가지 다 문서정리가 잘 되어있고 여러가지 커스텀을 할 수 있기 때문에 더 많은 이용을 원한다면 해당 문서를 조금 더 꼼꼼하게 찾아보면 될 것 같다. 특히 카카오맵 문서는 한글로 적혀있고 다양한 샘플도 있어서 참고하며 기능을 구현하기 어렵지 않았다.
지도를 구현하고 나면 콘솔에서 노란색 경고창이 뜨는 것을 볼 수 있다. A parser-blocking, cross site... 라며 뜨는데 이를 카카오 데브톡에서 검색을 해보니 동작을 하는데 크게 무리가 없다는 답변을 찾았다. 배포를 할 때 경고가 있으면 배포하다가 중간에 막히는 경우가 있는데 이 경고는 브라우저 배포시 크게 영향을 주지 않는지 vercel을 통해 샘플을 무리없이 배포할 수 있었다.
[참고]
- 주소를 위경도 변환해 주는 사이트(Dawul 주소전환) https://elwlsek.tistory.com/1504
- [React]카카오지도(KakaoMap) API 적용 https://velog.io/@lifeisbeautiful/React%EC%B9%B4%EC%B9%B4%EC%98%A4-API-%EC%A0%81%EC%9A%A9
- React Hooks / 리액트 훅스로 카카오맵 API 초간단하게 적용해보자! https://cotist.tistory.com/3
- 이미지 마커와 커스텀 오버레이 - Kakao 지도 Web API https://apis.map.kakao.com/web/sample/markerWithCustomOverlay
- 카카오 데브톡 | Gatsby 코드에서 map을 불러오는 코드를 작성중입니다 https://devtalk.kakao.com/t/gatsby-map/103810