import { useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { useLocation } from 'react-router-dom';
const { kakao } = window;
const SearchMapApi = ({ searchPlace }) => {
const location = useLocation();
const containerRef = useRef(null);
const [noResult, setNoResult] = useState(false);
useEffect(() => {
// Kakao 지도 API 스크립트 동적으로 추가
const script = document.createElement('script');
script.async = true;
script.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${import.meta.env.VITE_KAKAO_MAP_API_KEY}&libraries=services,drawing&autoload=false`;
document.body.appendChild(script);
// 스크립트가 로드된 후에 지도를 생성하도록 함
script.onload = () => {
window.kakao.maps.load(() => {
if (containerRef.current) {
const mapOption = {
center: new window.kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표
level: 9, // 지도의 확대 레벨
};
const map = new window.kakao.maps.Map(containerRef.current, mapOption);
const ps = new window.kakao.maps.services.Places(map);
// console.log(ps);
const placesSearchCB = (data, status) => {
if (status === window.kakao.maps.services.Status.OK) {
setNoResult(false);
displayPlaces(data);
} else if (status === window.kakao.maps.services.Status.ZERO_RESULT) {
setNoResult(true);
return;
} else if (status === window.kakao.maps.services.Status.ERROR) {
console.log(status);
return;
}
};
ps.keywordSearch(searchPlace, placesSearchCB);
// 지도에 마커를 생성하고 표시한다
var marker = new window.kakao.maps.Marker({
position: new window.kakao.maps.LatLng(37.56819, 126.98284), // 마커의 좌표
map: map // 마커를 표시할 지도 객체
});
// 마커에 클릭 이벤트를 등록한다 (우클릭 : rightclick)
window.kakao.maps.event.addListener(marker, 'click', function() {
alert('마커를 클릭했습니다!');
});
// // 검색 결과 목록과 마커를 표출하는 함수입니다
// if (searchPlace !== "") {
// const displayPlaces = (places) => {
// const listEl = document.getElementById('placesList'),
// menuEl = document.getElementById('menu_wrap'),
// fragment = document.createDocumentFragment(),
// bounds = new window.kakao.maps.LatLngBounds(),
// listStr = '';
// // 검색 결과 목록에 추가된 항목들을 제거합니다
// removeAllChildNods(listEl);
// for ( var i=0; i <places.length; i++ ) {
// // 마커를 생성하고 지도에 표시합니다
// var placePosition = new window.kakao.maps.LatLng(places[i].y, places[i].x),
// marker = addMarker(placePosition, i),
// itemEl = getListItem(i, places[i]); // 검색 결과 항목 Element를 생성합니다
// // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
// // LatLngBounds 객체에 좌표를 추가합니다
// bounds.extend(placePosition);
// // 마커와 검색결과 항목에 mouseover 했을때
// // 해당 장소에 인포윈도우에 장소명을 표시합니다
// // mouseout 했을 때는 인포윈도우를 닫습니다
// (function(marker, title) {
// window.kakao.maps.event.addListener(marker, 'mouseover', function() {
// displayInfowindow(marker, title);
// });
// window.kakao.maps.event.addListener(marker, 'mouseout', function() {
// infowindow.close();
// });
// itemEl.onmouseover = function () {
// displayInfowindow(marker, title);
// };
// itemEl.onmouseout = function () {
// infowindow.close();
// };
// })(marker, places[i].place_name);
// fragment.appendChild(itemEl);
// }
// // 검색결과 항목들을 검색결과 목록 Element에 추가합니다
// listEl.appendChild(fragment);
// menuEl.scrollTop = 0;
// // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
// map.setBounds(bounds);
// }
// // // 검색결과 항목을 Element로 반환하는 함수입니다
// // function getListItem(index, places) {
// // var el = document.createElement('li'),
// // itemStr = '<span class="markerbg marker_' + (index+1) + '"></span>' +
// // '<div class="info">' +
// // ' <h5>' + places.place_name + '</h5>';
// // if (places.road_address_name) {
// // itemStr += ' <span>' + places.road_address_name + '</span>' +
// // ' <span class="jibun gray">' + places.address_name + '</span>';
// // } else {
// // itemStr += ' <span>' + places.address_name + '</span>';
// // }
// // itemStr += ' <span class="tel">' + places.phone + '</span>' +
// // '</div>';
// // el.innerHTML = itemStr;
// // el.className = 'item';
// // return el;
// // }
// // // 마커를 생성하고 지도 위에 마커를 표시하는 함수입니다
// // function addMarker(position, idx, title) {
// // var imageSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/marker_number_blue.png', // 마커 이미지 url, 스프라이트 이미지를 씁니다
// // imageSize = new kakao.maps.Size(36, 37), // 마커 이미지의 크기
// // imgOptions = {
// // spriteSize : new kakao.maps.Size(36, 691), // 스프라이트 이미지의 크기
// // spriteOrigin : new kakao.maps.Point(0, (idx*46)+10), // 스프라이트 이미지 중 사용할 영역의 좌상단 좌표
// // offset: new kakao.maps.Point(13, 37) // 마커 좌표에 일치시킬 이미지 내에서의 좌표
// // },
// // markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imgOptions),
// // marker = new kakao.maps.Marker({
// // position: position, // 마커의 위치
// // image: markerImage
// // });
// // marker.setMap(map); // 지도 위에 마커를 표출합니다
// // markers.push(marker); // 배열에 생성된 마커를 추가합니다
// // return marker;
// // }
// // // 지도 위에 표시되고 있는 마커를 모두 제거합니다
// // function removeMarker() {
// // for ( var i = 0; i < markers.length; i++ ) {
// // markers[i].setMap(null);
// // }
// // markers = [];
// // }
// // // 검색결과 목록 하단에 페이지번호를 표시는 함수입니다
// // function displayPagination(pagination) {
// // var paginationEl = document.getElementById('pagination'),
// // fragment = document.createDocumentFragment(),
// // i;
// // // 기존에 추가된 페이지번호를 삭제합니다
// // while (paginationEl.hasChildNodes()) {
// // paginationEl.removeChild (paginationEl.lastChild);
// // }
// // for (i=1; i<=pagination.last; i++) {
// // var el = document.createElement('a');
// // el.href = "#";
// // el.innerHTML = i;
// // if (i===pagination.current) {
// // el.className = 'on';
// // } else {
// // el.onclick = (function(i) {
// // return function() {
// // pagination.gotoPage(i);
// // }
// // })(i);
// // }
// // fragment.appendChild(el);
// // }
// // paginationEl.appendChild(fragment);
// // }
// // // 검색결과 목록 또는 마커를 클릭했을 때 호출되는 함수입니다
// // // 인포윈도우에 장소명을 표시합니다
// // function displayInfowindow(marker, title) {
// // var content = '<div style="padding:5px;z-index:1;">' + title + '</div>';
// // infowindow.setContent(content);
// // infowindow.open(map, marker);
// // }
// // // 검색결과 목록의 자식 Element를 제거하는 함수입니다
// // function removeAllChildNods(el) {
// // while (el.hasChildNodes()) {
// // el.removeChild (el.lastChild);
// // }
// // }
// // 크기를 변경한 이후에는 반드시 map.relayout 함수를 호출
// }
const relayout = () => {
map.relayout();
};
// 예시: 지도 크기 변경 후 재배치
relayout();
}
});
// // 장소 검색 불러오기
// window.kakao.maps.load(() => {
// })
};
// 컴포넌트 언마운트 시에 스크립트 제거
return () => {
document.body.removeChild(script);
};
}, [location.pathname, searchPlace]);
return (
<div
ref={containerRef}
id="map"
style={{ width: "100%", height: "219px", borderRadius: "20px"}}
></div>
);
};
SearchMapApi.propTypes = {
searchPlace: PropTypes.string
};
export default SearchMapApi;
- GET http://dapi.kakao.com/v2/local/search/keyword.json?query=&page=1&size=15 400 (Bad Request).가 뜨는 이유를 모르겠습니다.
- 현재 검색목록에 대한 함수도 사용하지 않고, 마커만 생성하는데 마커도 생성이 안됩니다.
[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.