https://apis.map.kakao.com/web/sample/addr2coord/
https://apis.map.kakao.com/web/documentation/
getCenter 메서드와 같은 설명은 2번째 링크 documentation를 참고할 수 있습니다.
카카오 개발자 페이지에서 appkey를 발급받아서 사용해야합니다.
원하는 동작은 다음과 같습니다.
환경은 Next14의 App 라우터입니다.
카카오 지도의 스크립트를 사용할 컴포넌트는 윈도우를 사용해야해서 클라이언트 컴포넌트로 작성해야 합니다.
import Script from 'next/script'
next/script를 사용하여 카카오 지도 API 스크립트를 비동기적으로 로드합니다. 이는 페이지 로딩 속도를 향상시킵니다.
const [address, setAddress] = useState('')
address 상태 변수를 정의하여 지도 중심의 주소를 저장합니다.
const loadKaKaoMap = () => {
// 카카오 지도 API가 로드된 후 실행될 콜백 함수
window.kakao.maps.load(() => {
// 지도를 표시할 HTML 요소를 가져옵니다.
const mapContainer = document.getElementById('map');
// 지도의 초기 설정 옵션을 지정합니다.
const mapOption = {
// 지도의 중심 좌표를 설정합니다. (서울시청 기준)
center: new window.kakao.maps.LatLng(37.5667, 126.9782),
// 지도의 확대 레벨을 설정합니다.
level: 1,
};
// 지도를 생성합니다.
const map = new window.kakao.maps.Map(mapContainer, mapOption);
// 마커를 생성하고 지도의 중심에 위치시킵니다.
const marker = new window.kakao.maps.Marker({
position: map.getCenter(),
map: map,
});
// 주소를 변환할 Geocoder 객체를 생성합니다.
const geocoder = new window.kakao.maps.services.Geocoder();
// 좌표를 주소로 변환하는 함수입니다.
const updateAddress = (coords) => {
geocoder.coord2Address(
coords.getLng(),
coords.getLat(),
(result, status) => {
if (status === window.kakao.maps.services.Status.OK) {
// 변환된 주소를 가져옵니다.
const detailAddr = result[0].road_address
? result[0].road_address.address_name
: result[0].address.address_name;
// 변환된 주소를 상태 변수에 저장합니다.
setAddress(detailAddr);
}
}
);
};
// 초기 지도 중심의 주소를 변환합니다.
updateAddress(map.getCenter());
// 지도의 중심이 변경될 때마다 실행될 이벤트 리스너를 추가합니다.
window.kakao.maps.event.addListener(map, 'idle', function () {
// 지도의 새로운 중심 좌표를 가져옵니다.
const center = map.getCenter();
// 마커를 새로운 중심 좌표로 이동시킵니다.
marker.setPosition(center);
// 새로운 중심 좌표의 주소를 변환하여 업데이트합니다.
updateAddress(center);
});
});
};
지도 초기화: 지도와 마커를 초기화하고 지도 중심을 설정합니다.
주소 변환 함수: geocoder.coord2Address를 사용하여 좌표를 주소로 변환합니다.
중심 좌표 변경 이벤트 리스너: idle 이벤트를 사용하여 지도의 중심이 변경될 때마다 마커 위치를 지도 중심으로 업데이트하고, 주소를 변환하여 상태 변수 address에 저장합니다.
useEffect(() => {
console.log(address)
}, [address])
address 상태가 변경될 때마다 콘솔에 현재 주소를 출력합니다.
동작을 확인할 수 있습니다.
return (
<>
<Script
strategy="afterInteractive"
src={`//dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.NEXT_PUBLIC_KAKAO_MAP_CLIENT}&libraries=services,clusterer,drawing&autoload=false`}
onReady={loadKaKaoMap}
/>
<div id="map" style={{ width: '100%', height: '650px' }}></div>
<div>현재 주소: {address}</div>
</>
)
Next Script 컴포넌트를 사용하여 카카오 지도 API 스크립트를 로드하고, 로드가 완료되면 loadKaKaoMap 함수를 실행합니다. 이때 스크립트 src 파라미터에 autoload=false를 꼭 추가해야 합니다. useEffect로 동작 순서를 관리하지 않아도됩니다.
appkey: 카카오 개발자 사이트에서 발급받은 앱 키를 지정합니다.
autoload=false: 스크립트 로드 후 자동으로 API를 초기화하지 않도록 설정합니다. 이렇게 하면 스크립트를 로드한 후 직접 초기화할 수 있습니다.
libraries=services,clusterer,drawing: 추가 라이브러리(서비스, 클러스터러, 드로잉)를 로드하여 지도 API의 기능을 확장합니다.
이 설명을 참고하여 코드를 이해하고, 필요에 맞게 사용할 수 있습니다.
최종 코드
'use client'
import Script from 'next/script'
import { useEffect, useState } from 'react'
declare global {
interface Window {
kakao: any
}
}
const SearchMap = () => {
const [address, setAddress] = useState('')
const loadKaKaoMap = () => {
window.kakao.maps.load(() => {
const mapContainer = document.getElementById('map')
const mapOption = {
center: new window.kakao.maps.LatLng(37.5667, 126.9782),
level: 1,
}
const map = new window.kakao.maps.Map(mapContainer, mapOption)
const marker = new window.kakao.maps.Marker({
position: map.getCenter(),
map: map,
})
const geocoder = new window.kakao.maps.services.Geocoder()
const updateAddress = (coords: any) => {
geocoder.coord2Address(
coords.getLng(),
coords.getLat(),
(result: any, status: any) => {
if (status === window.kakao.maps.services.Status.OK) {
const detailAddr = result[0].road_address
? result[0].road_address.address_name
: result[0].address.address_name
setAddress(detailAddr)
}
}
)
}
updateAddress(map.getCenter())
window.kakao.maps.event.addListener(map, 'idle', function () {
const center = map.getCenter()
marker.setPosition(center)
updateAddress(center)
})
})
}
useEffect(() => {
console.log(address)
}, [address])
return (
<>
<Script
strategy="afterInteractive"
src={`//dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.NEXT_PUBLIC_KAKAO_MAP_CLIENT}&libraries=services,clusterer,drawing&autoload=false`}
onReady={loadKaKaoMap}
/>
<div id="map" style={{ width: '100%', height: '650px' }}></div>
</>
)
}
export default SearchMap