React - Kakao Maps API 이용하기(feat. 커스텀 오버레이)

보윤이의 기술 블로그·2022년 4월 24일
0

React

목록 보기
11/18
post-thumbnail

1. 구현하고 싶었던 기능

  • kakao map API 를 이용하여 리스트에 있는 숙소들의 위치를 보여주고 해당 숙소의 금액을 보여주기(커스텀 오버레이를 활용)
  • mouseover / mouseout 기능

2. 로직 설명

1) Kakao Maps API 라이브러리를 사용하여 Staylist 페이지에 지도 불러오기
2) index.html 에 Kakao Maps API 라이브러리를 추가
3) Kakao Maps Sample 데이터를 리액트 형식에 맞게 수정하여 작성
4) BE와 통신으로 주고받을 데이터 내 latitude, longitude 를 사용하여 카카오맵 지도에 커스텀 오버레이를 활용하여 표시
5) 커스텀 오버레이에 mouseover / mouseout 기능을 구현
커스텀 오버레이는 사용자가 자유롭게 컨텐츠를 구성하고 이벤트를 제어할 수 있어 별도의 이벤트 메소드를 제공하지 않기 때문에, 바닐라 자바스크립트로 이벤트를 직접 만들어서 기능을 부여해야 한다.

3. 구현한 코드

/*global kakao*/
import React, { useEffect } from 'react';

const StayMap = ({ fetchData }) => {
  useEffect(() => {
    let mapContainer = document.getElementById('map'), // 지도를 표시할 div
      mapOption = {
        center: new kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표
        level: 10, // 지도의 확대 레벨
      };

    let map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다

    // 지도에 마커를 표시합니다
    const displayMarkers = data => {
      const markerPosition = new kakao.maps.LatLng(
        data.latitude,
        data.longitude
      );
	  // 지도 위 커스텀 오버레이 에 줄 효과
      const contentInner = `<div style="padding: 10px 15px;
      position: relative; bottom:20px; border-radius: 28px; background-color: rgb(255, 255, 255);
      box-shadow: rgb(0 0 0 / 4%) 0px 0px 0px 1px, rgb(0 0 0 / 18%) 0px 2px 4px;
      color: rgb(34, 34, 34); text-align:center;
      font-size: 14px;
      font-weight: 880;"> ₩ ${Number(data.price)}</div>`;

      const content = document.createElement('div');
      content.innerHTML = contentInner;
      content.addEventListener('mouseover', () => {
        blackOverlay.setMap(map);
        whiteOverlay.setMap(null);
      });

      const blackContentInner = `<div style="padding: 10px 15px;
      position: relative; bottom:20px; border-radius: 28px; background-color: black;
      box-shadow: rgb(0 0 0 / 4%) 0px 0px 0px 1px, rgb(0 0 0 / 18%) 0px 2px 4px;
      color: rgb(255, 255, 255); text-align:center;
      font-size: 14px;
      font-weight: 880;"> ₩ ${Number(data.price)}</div>`;

      const blackContent = document.createElement('div');
      blackContent.innerHTML = blackContentInner;
      blackContent.addEventListener('mouseout', () => {
        whiteOverlay.setMap(map);
        blackOverlay.setMap(null);
      });

      const whiteOverlay = new kakao.maps.CustomOverlay({
        content: content,
        map: map,
        position: markerPosition,
      });

      const blackOverlay = new kakao.maps.CustomOverlay({
        content: blackContent,
        map: null,
        position: markerPosition,
      });
    };

    // 지도에 확대 축소 컨트롤을 생성한다
    let zoomControl = new kakao.maps.ZoomControl();

    // 지도의 우측에 확대 축소 컨트롤을 추가한다
    map.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);

    fetchData.map(data => {
      return displayMarkers(data);
    });
  }, [fetchData]);

  return <div id="map" style={{ width: '100%', height: '100vh' }} />;
};

export default StayMap;
profile
어제보다 오늘 더 성장하는 프론트엔드 개발자

0개의 댓글