최종프로젝트
kakaoMap 라이브러리
- 카카오맵을
react-kakao-maps-sdk
라이브러리를 사용하여 다시 수정하였다.
- 사용 이유
- 공식 문서에 튜토리얼과 사용방법이 상세하게 나와있다.
- 기존 코드보다 사용하기 편하고 직관적이다.
- 카카오톡 api는 리액트를 사용함에도 불구하고 자바스크립트 용어를 써야했는데 라이브러리는 그 점이 없다.
import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';
import styled from 'styled-components';
const DetailMap = () => {
const MapRef = useRef(null);
const { state: detailData } = useLocation();
const detailLocation = new window.kakao.maps.LatLng(
detailData.lat,
detailData.lon,
);
useEffect(() => {
let options = {
center: detailLocation,
level: 3,
};
let map = new window.kakao.maps.Map(MapRef.current, options);
const zoomControl = new window.kakao.maps.ZoomControl();
map.addControl(zoomControl, window.kakao.maps.ControlPosition.RIGHT);
new window.kakao.maps.Marker({
map,
position: detailLocation,
});
}, []);
return <DetailPageMap ref={MapRef}></DetailPageMap>;
};
export default DetailMap;
const DetailPageMap = styled.div`
width: 500px;
height: 500px;
`;
import { useLocation } from 'react-router-dom';
import styled from 'styled-components';
import { Map, MapMarker } from 'react-kakao-maps-sdk';
const DetailMap = () => {
const { state: detailData } = useLocation();
const detailLocation = {
lat: detailData.lat,
lng: detailData.lon,
};
return (
<DetailPageMap center={detailLocation}>
<MapMarker position={detailLocation}>
<div>{detailData.title}</div>
</MapMarker>
</DetailPageMap>
);
};
export default DetailMap;
const DetailPageMap = styled(Map)`
width: 500px;
height: 500px;
`;
지도로 주변위치 키워드 검색
- 카카오톡 api에서 기본적으로 제공해주는 기능으로 '이태원 맛집' 이라는 키워드로 검색하면 그와 관련된 data를 배열값으로 받을 수 있다.
const ps = new kakao.maps.services.Places();
ps.keywordSearch('이태원 맛집', (data, status, _pagination) => {
네이버 api와 카카오맵 데이터 연동
- 키워드 검색을 하면 카카오맵에서 data를 제공해준다고 위에서 말했는데 data에서 이미지 파일이 없어서 네이버 api와 연동하였다.
- 함수
onSubmit
은 위치를 검색했을 때 지도에 data를 가져와 마커표시해주는 함수이다.
markers.push
를 해줄 때 네이버 api의 params의 query 값에 data의 상호명을 넣어 이미지 값을 검색하게 하였다.
- 검색한 이미지 데이터 값을 markers.push 할 때 같이 넣어주었다.
- 문제점
- 맨 처음 api를 사용할 때
CORS Error
가 발생하였다.
- package.json 파일에서
"proxy" :"https://openapi.naver.com"
문구를 추가해주었다.
- 배포할 땐 안된다고 해서 다른 방법을 찾아야한다.
- for 문을 통해 여러번 요청하다 보니
과도한 요청이라는 Error
발생
import axios from 'axios';
import React, { useEffect, useRef, useState } from 'react';
import { Map, MapMarker } from 'react-kakao-maps-sdk';
import { useRecoilState, useRecoilValue } from 'recoil';
import styled from 'styled-components';
import { MapSearchValue } from '../../../atoms';
import MapModal from './MapModal';
interface IMap {
position: {
lat: string;
lng: string;
};
content: string;
}
const Maps = () => {
const [info, setInfo] = useState<any>();
const [markers, setMarkers] = useState<any>([]);
const [map, setMap] = useState<any>();
const [searchValue, setSearchValue] = useRecoilState(MapSearchValue);
const searchValueChangeHandler = (
event: React.FormEvent<HTMLInputElement>,
) => {
setSearchValue({ value: event.currentTarget.value });
};
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const ps = new kakao.maps.services.Places();
ps.keywordSearch(searchValue.value, (data, status, _pagination) => {
if (status === kakao.maps.services.Status.OK) {
const bounds = new kakao.maps.LatLngBounds();
let markers: any = [];
console.log('ok');
getSearchKeyWord().then(async () => {
const NAVER_CLIENT_ID = 'ZDK5Gc_XwH219r8fwyIt';
const NAVER_CLIENT_SECRET = 'VRu_0jKjhT';
for (let i = 0; i < data.length; i++) {
const {
data: { items },
} = await axios.get('/v1/search/image', {
params: { query: data[i].place_name, start: 1, display: 1 },
headers: {
'X-Naver-Client-Id': NAVER_CLIENT_ID,
'X-Naver-Client-Secret': NAVER_CLIENT_SECRET,
},
});
console.log('items.link', items);
markers.push({
position: {
lat: data[i].y,
lng: data[i].x,
},
content: data[i].place_name,
address: data[i].address_name,
category: data[i].category_group_name,
img: items[0].link,
});
bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x));
}
setMarkers(markers);
map.setBounds(bounds);
});
}
});
};
useEffect(() => {
if (!map) return;
}, []);
const getSearchKeyWord = () => {
};
const [openModal, setOpenModal] = useState(false);
return (
<>
{}
{}
<form onSubmit={onSubmit}>
<input
onChange={searchValueChangeHandler}
type="text"
value={searchValue.value}
/>
</form>
<Map
center={{
lat: 37.566826,
lng: 126.9786567,
}}
style={{
width: '100%',
height: '350px',
}}
level={3}
onCreate={setMap}
>
{markers.map((marker: any) => (
<MapMarker
key={`marker-${marker.content}-${marker.position.lat},${marker.position.lng}`}
position={marker.position}
onClick={() => setInfo(marker)}
>
{info && info.content === marker.content && (
<div style={{ color: '#000' }}>{marker.content}</div>
)}
</MapMarker>
))}
</Map>
</>
);
};
export default Maps;
const Wrap = styled.div`
background-color: grey;
width: 700px;
height: 600px;
`;