React / 카카오 지도 API - 위치에 맞게 게시글 불러오기

support·2022년 3월 28일
0

Final Project

목록 보기
7/10
post-thumbnail

지도를 이동할 때마다 지도안의 주소에 있는 게시글과 마커의 목록만 나오도록 만들어야 했다

지도를 작게 줄였을때 전국의 모든 게시물에 대한 요청을 보낼 수 없기 때문에 지도의 레벨에 따라서 게시글의 유무를 정했다

지도의 레벨이 6이상이면 요청을 보내지 않고
6보다 아래라면 요청을 보내 지도안의 목록을 받아오고
그 목록으로 마커를 생성하는 코드를 짰다

지도안의 목록을 받아오기 위해서 모집글을 쓸 때 주소를 위도와 경도로 바꿔서 데이터 베이스에 넣어줬고
지도의 남서쪽 좌표와 북동쪽 좌표를 구해서 그 안에 있는 글만 받아오는 코드를 작성했다
지도의 크기를 바꾸거나 드래그가 끝나면 axios 요청을 보낸다

const [state, setState] = useState({
  // 지도의 초기 위치
  center: { lat: 37.49676871972202, lng: 127.02474726969814 },
  // 지도 위치 변경시 panto를 이용할지(부드럽게 이동)
  isPanto: true,
});
  // 마커 표시 데이터
const MarkerPost = useSelector((state)=> state.postsReducer.posts)

// 지도가 생성될 때, state가 바뀔때 지도의 정보 가져옴
useEffect(()=>{
  handleMapInfo()
}, [map, state])

// 지도의 레벨에 맞춰 목록 출력
useEffect(()=>{
  if(info && info.level <= 5){
    dispatch(showPostList(info))
  }else if(info && info.level >= 6){
    dispatch(showPostList())
  }    
}, [info])

// 지도의 정보 가져옴
const handleMapInfo = () => {
  {map && (setInfo({
    level: map.getLevel(),
    swLatLng: {
      lat: map.getBounds().getSouthWest().getLat(),
      lng: map.getBounds().getSouthWest().getLng(),
    },
    neLatLng: {
      lat: map.getBounds().getNorthEast().getLat(),
      lng: map.getBounds().getNorthEast().getLng(),
    },
  }))
  }

<Map // 지도를 표시할 Container
	center={state.center}
	isPanto={state.isPanto}
	style={{
       // 지도의 크기
       width: "100%",
       height: "70vh",
      }}
      level={4} // 지도의 확대 레벨
	onCreate={(map) => setMap(map)}
	onZoomChanged={(map) => setLevel(map.getLevel())}
	onIdle={handleMapInfo} // 중심 좌표나 확대 수준이 변경됐을 때
>

{MarkerPost && 
  MarkerPost.map((el, index) => (
    <MapMarker
      key={index}
   	  position={{ lat: el.lat, lng: el.lng }} // 마커 표시 위치
      image={{
        src: "https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/markerStar.png", // 마커이미지 주소
        size: {
          widht: 24,
          height: 35
         }, // 마커이미지 크기
      }}
  />))
 }

제일 시간을 많이 썼던 건 지도의 레벨으로 게시글을 요청하고 요청하지 않는 부분이었다
리덕스에 게시글을 reset하는 함수를 하나 더 만들어서 해결 할 수 있었다

const showPostReset = () => {
  return {
    type : RESET_POST_LIST,
    payload : null,
  }
}

export const showPostList = (info) => {
  return (dispatch) => {
    if(!info){
      dispatch(showPostReset())
    }else{
      axios.get(`${process.env.REACT_APP_API_URL}/contents?start=${info.swLatLng.lat},${info.swLatLng.lng}&end=${info.neLatLng.lat},${info.neLatLng.lng}`)
      .then(post => dispatch(showPostSuccess(post)))
      .catch(err=> console.log(err))
    }
  }
}

0개의 댓글