Dandy Now!
  • [React.js] 네이버 지도 API 마커 리렌더링시 누적(쌓이는) 현상(마커 클러스터)
    2024년 02월 29일 10시 03분 08초에 업로드 된 글입니다.
    작성자: DandyNow
    728x90
    반응형

    1. 마커 누적 현상

    마커를 커스텀 오버레이로 만들어 사용했다. 그 이유는 마커에 서버로부터 받은 데이터를 표시해야 했기 때문이다. 동적인 데이터를 렌더링 하기 위해 useEffect 훅을 사용했다. 그런데 데이터가 변경(리렌더링) 될 때마다 동일한 위치에 동일한 마커가 계속해서 쌓이는 현상이 발생했다!

     

    2. useEffect의 return 적용

    function MarkerCluster({ data }) {
      const navermaps = useNavermaps();
      const map = useMap();
      const [cluster, setCluster] = useState(null);
    
      // (생략)
    
      const MarkerClustering = makeMarkerClustering(window.naver);
    
      useEffect(() => {
        if (!navermaps || !data) return; // 서버의 데이터는 비동기적(promise)으로 처리되기 때문에 data 값이 없다면 return!
    
        const markers = [];
    
        for (let i = 0; i < data.length; i++) {
          const { name, latitude, longitude } = data[i];
    
          const content = ReactDOMServer.renderToString(
              // (생략)
              <div className="custom-marker-title-nosign">{name}</div>
              // (생략)
          );
    
          let marker = new navermaps.Marker({
            position: new navermaps.LatLng(latitude, longitude),
            icon: {
              content,
              origin: new navermaps.Point(0, 0),
              anchor: new navermaps.Point(40, 58),
            },
          });
          navermaps.Event.addListener(marker, 'click', e => console.log(name)); // 마커에 클릭 이벤트 적용
    
          markers.push(marker);
        }
    
        const cluster = new MarkerClustering({
          // (생략)
          markers,
          // (생략)
        });
    
        setCluster(cluster);
    
        return () => setCluster(cluster.setMap(null)); // 중요!!! 기존 오버레이 제거
      }, [navermaps, apList]);
    
      return cluster && <Overlay element={cluster} />;
    }

    😉 위 코드는 주제에 관련된 것만 남기고 최대한 생략하고자 하였다.  

     

    위 코드는 useEffect 훅을 통해 리렌더링 될 때 동일 오버레이가-중첩-누적되는 현상을 개선한 코드이다. 가장 핵심 적인 코드는 useEffect의 return이다. useEffect의 return값은 해당 effect가 더 이상 실행할 필요가 없을 때 청소해 주는 역할을 한다. 이 용도에 대한 것은 react 공식문서에 나오는 내용이므로 별 문제없다. 그런데 무엇을 청소해야 한다는 말인가?! 네이버지도 API 공식문서에서 그 해답을 찾을 수 있다(그림 1 참조). 오버레이의 setMap() 메서드의 인수로 null을 넣어주면 된다.

    [그림 1] 공식 문서에서 설명하는 오버레이 삭제

    😉네이버지도 API 공식문서 : https://navermaps.github.io/maps.js.ncp/docs/tutorial-6-CustomOverlay.html

     

     

    728x90
    반응형
    댓글