카카오 맵 API 적용하기
카카오 개발자 사이트
https://developers.kakao.com/카카오 개발자 사이트에 들어가면 다양한 카카오 API를 이용할 수 있다.
최근 떨어진 내 카카오주식을 손절했지만 유용한 API를 제공해주는 카카오가 밉지만은 않다.카카오 API를 사용하는 방법은 조금 어려웠지만 권한은 아무에게나 허용하는 것 같았다.
카카오로그인을 한뒤 애플리케이션과 사업자명을 임의로 추가하면 키를 부여받을 수 있었다.그 중 여러사이트에서 유용하게 쓰이는 카카오맵 API를 적용하는 방법을 배웠다.
그리고 내 마켓 사이트에 적용해보았다.📔 결과물
등록할때 지도마커의 좌표(위도, 경도)가 그대로 백엔드에 등록되면서
불러올때는 그 좌표를 query를 통해 불러오면서 지도에 그 위치를 표시할 수 있게해주었다.💻 코드리뷰
market-write.container
(작성 페이지)
kakao
라는 변수를 인식 못하기 때문에 카카오의 타입을 먼저 컴퓨터에 알려준다.declare const window: typeof globalThis & { kakao: any; };
- 위도(
Lat
) 경도(Lng
)를useState()
를 통해 담아준다.variables
에 위도와 경도 값을 넣어준다.export default function MarketWrite(props) { const [myLat, setMyLat] = useState(""); const [myLng, setMyLng] = useState(""); async function onClickUploadProduct(data) { try { const result = await createUseditem({ variables: { createUseditemInput: { ...data, useditemAddress: { lat: myLat, lng: myLng, }, }, }, }); console.log(data); alert("상품을 등록합니다~"); router.push(`/market/market-detail/${result.data.createUseditem._id}`); } catch (error) { console.log(error.message); } }
- 여기가 실질적으로 카카오 맵을 이용하는 부분이다.
useEffect
를 사용하는 이유
useEffet
를 사용하지 않았다면 페이지가 렌더되는 시점에서document
가undefined
한 값을 받아오게된다.
이는 서버사이드 렌더링의 특징 중 하나인데
document
를 사용하는 시점을document
가 생성된 시점 이후로 변경해주는 코드가 필요하다.
그래서useEffect
를 통해 페이지가 렌더되고document
객체가 생성된 이후에서 카카오맵을 호출할 수 있도록 변경해준다.
Next JS
에서 카카오맵 코드를 만져줘야하는 이유
가이드라인에서 가져온 코드이지만 여러가지 수정을 해주었다.
그 이유는React
에서, 특히Next JS
에서는HTML
로 접근할 수 있는 방법이 한정적이기 때문이다.
또한 위에 말한 서버사이드 렌더링을 지원하는Next JS
의 방식 때문에 그대로 구현하면 오류가 발생 할 수 밖에 없다.useEffect(() => { const script = document.createElement("script"); script.src = "//dapi.kakao.com/v2/maps/sdk.js?autoload=false&appkey=자신의 앱키"; document.head.appendChild(script); script.onload = () => { window.kakao.maps.load(function () { const container = document.getElementById("map"); // 지도를 담을 영역의 DOM 레퍼런스 const options = { // 지도를 생성할 때 필요한 기본 옵션 center: new window.kakao.maps.LatLng(37.485148, 126.895113), // 지도의 중심좌표. level: 3, // 지도의 레벨(확대, 축소 정도) }; const map = new window.kakao.maps.Map(container, options); console.log(map); const marker = new window.kakao.maps.Marker({ // 지도 중심좌표에 마커를 생성합니다 position: map.getCenter(), }); marker.setMap(map); window.kakao.maps.event.addListener( map, "click", function (mouseEvent: { latLng: any }) { // 클릭한 위도, 경도 정보를 가져옵니다 const latlng = mouseEvent.latLng; // 마커 위치를 클릭한 위치로 옮깁니다 marker.setPosition(latlng); setMyLat(latlng.getLat()); setMyLng(latlng.getLng()); } ); }); }; }, []); }
market-write.presenter
- 카카오맵을 사용할때 꼭
HTML
부분에id
가map
인div
가 있어야한다.
그래야 카카오맵이id
가map
인div
를 추적해서 맵을 표시하게 해준다.
value
가 그대로 위도와 경도가 찍히게끔 해준다.<LocationWrapper> <CommonLabel name="거래위치" /> <Location id="map"></Location> </LocationWrapper> <GPSText type="text" value={props.myLat} readOnly /> <GPSText type="text" value={props.myLng} readOnly />
market-detail.container
(상세 페이지)
market-writer.container
의 카카오맵 코드와 비슷하게 적어주면 된다.
다만, 최초 위도 경도가query
에서 받은 위도 경도가 찍히게 해주어야한다.
- 코드를 작성하면서
query
에서 받은 위도 경도가 찍히지 않는 현상이 있었는데,
useEffect의 빈배열 ,[]을 빼주니 해결되었다.
,[]은 렌더링을 한번만 하겠다는 의미인데 query가 되기전에 카카오맵이 먼저 불러와져버려서
불러오지 못 하는 것이다. 만약 ,[]를 빼준다면 계속 렌더링 되기 때문에 잘 받아와진다.