지난 게시글에서 실제 법정동의 좌표를 가져와 모든 동의 폴리곤, 폴리라인을 그려냈다.
모든 동의 좌표가 동시에 그려지는 것은 의미가 없으니 동에 해당하는 Marker에 hover를 했을 때 그 동의 폴리곤, 폴리라인만 그려지게 할 것이다.
우선 가독성을 위해서 Map.js에 작성된 state 및 함수, 변수 등을 Custom hooks로 따로 정리한다.
usePolygon.js
import React, { useState } from 'react';
const usePolygon = () => {
const navermaps = window.naver.maps;
const [poly, setPoly] = useState([]);
let onHoverPaths = [];
const handleHoverCoordinate = data => {
setPoly(data.coordinate.coordinates[0][0]);
};
poly.forEach(coordinate => {
onHoverPaths.push(new navermaps.LatLng(coordinate[1], coordinate[0]));
});
return {
onHoverPaths,
handleHoverCoordinate,
};
};
export default usePolygon;
폴리곤과 폴리라인을 그리기 위해서 배열을 벗겨낸 후 좌표 데이터를
new navermaps.LatLng()
객체를 통해서 지도에 그려낼 수 있다.
이전 게시글에서 자세한 코드 확인하기
handleHoverCoordinate
함수를 통해 hover 되는 marker의 data를 인수로 받아 해당 data의 좌표값만 추출해 poly
에 할당한다.
이전에 작성한 코드는 handleHoverCoordinate
를 정의하는 대신 3개의 변수를 작성했다.
좌표값만 추출하기 위해서는 많은 변수를 사용하는 것보다 함수 하나만 작성하는 것이 hover 이벤트를 처리하는데 적합하다.
poly
에는 hover 되는 Marker에 해당하는 좌표값들이(폴리라인, 폴리곤) 배열 안에 담겨져있다.
이전 코드와 마찬가지로 forEach
메소드를 통해 'new navermap'을 통해 생성된 객체를 onHoverPaths 배열에 push 한다.
return
에 { }
를 작성하여 그 안에 export 할 함수나 변수 등을 작성하면 추후 import 하여 사용할 수 있다.
여기까지 custom hook을 만들어서 코드를 좀 더 깔끔하고 재활용성을 높이는 작업을 했다.
우선 usePolygon을 사용하기 위해서 사용할 곳에서 import한다.
Map.js
import usePolygon from '../../hooks/usePolygon';
function NaverMapAPI({ dongData }) {
const navermaps = window.naver.maps;
const { onHoverPaths, handleHoverCoordinate } = usePolygon();
//구조분해할당하여 usePolygon hook 가져오기
const [isMouseOn, setIsMouseOn] = useState(false);
//마우스 호버 되었을 때 true, 아웃 되었을 때 false
return (
<NaverMap
id="react-naver-maps-introduction"
style={{ width: '100vw', height: '90vh', borderTop: 'transparent' }}
defaultCenter={{ lat: 37.497175, lng: 127.027926 }}
defaultZoom={13}
>
{dongData.map(input => (
<>
<Marker
key={input.region_code}
position={
new navermaps.LatLng(input.x_coordinate, input.y_coordinate)
}
icon={{
content: `<div class="markerBox" >
<h1 class="markerCountText">${input.total_count}</h1>
<p class="markerText">${input.ub_myeon_dong}</p>
</div>`,
}}
title={input.ub_myeon_dong}
onMouseover={() => {
handleHoverCoordinate(input);
setIsMouseOn(true);
}}
onMouseout={() => {
mouseOut();
setIsMouseOn(false);
}}
/>
</>
))}
dongData
는 부모 컴포넌트인 Main.js에서 props로 넘겨 받았다.dongData
에는 Marker의 정보, Polygon, Polyline 정보가 모두 담겨있다.📢 Naver Map에서 hover 이벤트는 onMouseover
이다. onMouseOver
라고 작성하면 작동하지 않는다📢
과정 정리하기
역삼동 Marker에 mouseover 시 역삼동 좌표의 폴리곤과 폴리라인이 그려져야 한다. 역삼동의 좌표 데이터를 넘겨준다.
onMouseover
의 콜백함수로 usePloygon hook에서 import 한 handleHoverCoordinate
함수를 작성한다.
전달되는 인자는 dongData
의 input 즉, 각각의 데이터이다.
const handleHoverCoordinate = data => {
setPoly(data.coordinate.coordinates[0][0]);
};
//매개변수 data가 인자인 dongData의 input을 받는다.
//따라서 mouseover되는 객체의 데이터가 함수의 인자가 된다.
Marker에 mouseover
될 때 폴리곤과 폴리라인이 생성되고 mouseout
되면 생성되지 않는다.
모달창과 원리는 같다. 조건부 연산자를 사용하여 true 라면 폴리라인과 폴리곤이 보여지게 되고 false라면 보이지 않게 된다.
const [isMouseOn, setIsMouseOn] = useState(false);
초기값은 mouseover
되지 않은 상태에는 보이지 않기 때문에 false 값
mouseover
되면 isMouseOn
은 true
값을 가져 폴리곤과 폴리라인이 그려진다.
{isMouseOn && (
<>
<Polyline
clickable={true}
strokeColor="rgb(17, 135, 207)"
strokeStyle="solid"
strokeWeight={2}
path={onHoverPaths}
/>
<Polygon
fillColor="rgb(17, 135, 207)"
fillOpacity={0.35}
clickable={true}
paths={onHoverPaths}
/>
</>
)}
결과
개념과 구현하는 것이 난이도가 아주 높은 것은 아니었다.
다만 처음 사용하는 custom hook에 대한 개념을 확실히 알고 적용하는 과정, mouseover되는 객체의 데이터를 함수의 인자로 넘겨주는 과정, onMouseover 오타를 찾는 과정에서 오랜 시간이 걸렸다.
오래 걸리더라도 확실하게 알고 같은 실수를 반복하지 않기 위해 블로그를 작성하며 다시 정리한다.
이번 프로젝트를 통해 리액트를 좀 더 깊게 알게 되는 계기가 되었다.
custom hook으로 깔끔한 코드를 작성하고, 이벤트 객체를 함수의 인자로 넘겨주며 데이터를 활용하는 과정에서 어떤 로직으로 구현되는지 등