티스토리 뷰
kakao API 사용하기
api 키 발급 및 초기 설정은 아래 블로그 참고
https://rominlamp.tistory.com/20
지도 생성
지도 위치가 바뀔 때마다 상태를 변경해줘야 하니까 mapState를 만들어준다
초기값 좌표는 카카오 api 링크에 나온 좌표를 참고해서 넣자
function App() {
const [mapState, setMapState] = useState({
center: {
lat: 33.450701,
lng: 126.570667,
},
address: "",
errMsg: "",
});
return (
<div>
<Map
center={mapState.center}
style={{
width: "100%",
height: "100vh",
}}
level={3}
>
</Map>
</div>
);
}
export default App;
https://react-kakao-maps-sdk.jaeseokim.dev/docs/sample/map/basicMap
마커 생성
마커 상태관리를 위해 markerState를 만들고 초기값은 지도 좌표를 저장해 줬다(마커와 지도는 같은 위치에 있어야 하니까)
마커에 주소를 띄우기 위해 div에 style을 지정해 준다
* 지도와 마커는 같은 값을 저장하는데 따로 state를 만든 이유
처음엔 하나의 상태로 사용했지만 위치 저장 기능을 사용할 경우, 마커와 지도의 역할이 분리되어야 하기 때문에 상태를 나눠줬다
지도 - 사용자 움직임에 따라 상태가 변해야 한다
마커 - 지도 움직임에 따라 동일하게 상태가 변해야 하지만 위치를 저장할 경우 지도와 분리되어 고정 위치값을 가져야 한다
const [markerState, setMarkerState] = useState(mapState.center);
return (
<div>
<Map
center={mapState.center}
style={{
width: "100%",
height: "100vh",
}}
level={3}
>
<MapMarker position={markerState}>
<div
style={{
display: "inline",
padding: "10px",
color: "#000",
}}
>
{mapState.errMsg && mapState.errMsg}
</div>
</MapMarker>
</Map>
</div>
);
https://react-kakao-maps-sdk.jaeseokim.dev/docs/sample/overlay/basicMarker
geolocation으로 현재 위치에 마커 표시
GeoLocation는 내장 API로 별도 설치 없이 사용 가능하다
위도(latitude)와 경도(longitude)를 포함한 사용자의 위치 정보를 가져올 수 있고 navigator.geolocation 객체를 통해 접근할 수 있다
getCurrentAddress 함수를 통해 현재 위치가 있을 경우 해당 좌표를 지도와 마커에 저장한다
useEffect으로 컴포넌트가 마운트 될 때마다 getCurrentAddress 함수를 호출해 현 위치를 표시한다
없을 경우 error메시지 출력
* getCurrentAddress 함수에서 state에 직접 객체를 담지 않고 따로 객체를 만들어서 저장한 이유
getCurrentAddress 함수에서 다른 기능을 위해 mapState를 사용할 경우, useState가 비동기적으로 작동하기 때문에 바로 반영된 상태값을 사용할 수 없기 때문
useEffect(() => {
getCurrentAddress();
}, []);
const getCurrentAddress = () => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
const newCenter = {
lat: position.coords.latitude,
lng: position.coords.longitude,
};
setMapState((prev) => ({
...prev,
center: newCenter,
}));
setMarkerState(newCenter);
},
(err) => {
setMapState((prev) => ({ ...prev, errMsg: err.message }));
}
);
} else {
setMapState((prev) => ({
...prev,
errMsg: "현재 위치를 찾을 수 없습니다.",
}));
}
};
const [markerState, setMarkerState] = useState(mapState.center);
return (
<div>
<Map
center={mapState.center}
style={{
width: "100%",
height: "100vh",
}}
level={3}
>
<MapMarker position={markerState}>
<div
style={{
display: "inline",
padding: "10px",
color: "#000",
}}
>
{mapState.errMsg && mapState.errMsg}
</div>
</MapMarker>
</Map>
</div>
);
https://react-kakao-maps-sdk.jaeseokim.dev/docs/sample/overlay/geolocationMarker
https://developer.mozilla.org/ko/docs/Web/API/Geolocation_API
중심좌표 변경 이벤트 (지도가 움직이면 마커는 지도 중앙에 오도록)
centerChangeHandler 함수에 getCenter 메서드로 중심 좌표를 찾고 객체에 중심좌표 기준 위도와 경도를 담아준다
지도와 마커의 상태를 중심좌표로 변경해 준다(mapState, markerState)
const centerChangeHandler = (map:any) => {
const newCenter = map.getCenter();
const newPosition = {
lat: newCenter.getLat(),
lng: newCenter.getLng(),
};
setMapState((prev) => ({
...prev,
center: newPosition,
}));
setMarkerState(newPosition);
};
return (
<div>
<Map
center={mapState.center}
style={{
width: "100%",
height: "100vh",
}}
level={3}
onCenterChanged={(map) => centerChangeHandler(map)}
>
<MapMarker position={markerState}>
<div
style={{
display: "inline",
padding: "10px",
color: "#000",
}}
>
{mapState.errMsg && mapState.errMsg}
</div>
</MapMarker>
</Map>
</div>
);
https://react-kakao-maps-sdk.jaeseokim.dev/docs/sample/map/addMapCenterChangedEvent