Next.js 동적 지도 렌더링 이슈

스크린샷 2023-12-22 오후 3.50.49

import React, { useEffect } from 'react';

declare global {
  interface Window {
    kakao: any;
  }
  const kakao: any;
}

export default function KakaoMap() {
  useEffect(() => {
    const kakaoMapScript = document.createElement('script');
    kakaoMapScript.async = false;
    kakaoMapScript.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.NEXT_PUBLIC_MAP_KEY}&autoload=false`;
    document.head.appendChild(kakaoMapScript);

    const onLoadKakaoAPI = () => {
      const container = document.getElementById('map');
      window.kakao.maps.load(() => {
        const options = {
          center: new window.kakao.maps.LatLng(37.54699, 127.09598),
          level: 3,
        };
        const map = new window.kakao.maps.Map(container, options); // 지도를 생성합니다

        const imageSrc =
          'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/marker_red.png'; // 마커이미지의 주소입니다
        const imageSize = new window.kakao.maps.Size(64, 69); // 마커이미지의 크기입니다
        const imageOption = { offset: new window.kakao.maps.Point(27, 69) }; // 마커이미지의 옵션입니다. 마커의 좌표와 일치시킬 이미지 안에서의 좌표를 설정합니다.
        // 마커의 이미지정보를 가지고 있는 마커이미지를 생성합니다
        const markerImage = new window.kakao.maps.MarkerImage(
          imageSrc,
          imageSize,
          imageOption,
        );
        const markerPosition = new window.kakao.maps.LatLng(
          37.54699,
          127.09598,
        ); // 마커가 표시될 위치입니다

        // 마커를 생성합니다
        const marker = new window.kakao.maps.Marker({
          position: markerPosition,
          image: markerImage, // 마커이미지 설정
        });
        map.relayout();
        map.setCenter(new window.kakao.maps.LatLng(37.54699, 127.09598));
        marker.setMap(map);
      });
    };

    kakaoMapScript.addEventListener('load', onLoadKakaoAPI);
  }, []);

  return <div id="map" className="map-area" />;
}

이렇게 코드가 작성되어있고 사진과 같이 드래그로 이동 시 새로 렌더링 되지 못 하고 있습니다…

    map.relayout();
    map.setCenter(); 모두 사용하여도 이상이 생깁니다..

정말 감이 잡히지 않습니다…혹시 컴포넌트 렌더링 순서에 문제가 있을까요…?어떤 방법으로 해결하면 좋을 지 조언부탁드립니다.

스크린샷 2023-12-22 오후 4.16.56

좌측 하단 영역이 지도로 렌더링 되지 않으면(kakao 백 이미지일 경우)사진과 같이 이전 정보와 겹치 보여지는 현상도 있습니다.

(원인은 위와 같을 것으로 예상되오나 추가적으로 말씀드려봅니다…!)

  1. 해당 컴포넌트 렌더링 조건은 ‘페이지 이동입니다’ (모달 x)
  2. 컴포넌트 분리하여 사용하는 곳에 이렇게 사용하여

https://devtalk.kakao.com/t/api/131077에 내용을 참고하여
지도를 표시할 영역의 크기가 잡히기 전이 아닌 div를 먼저 생성하고 부르도록수정하였지만 동일하게 나옵니다…

    <div id="map" className="map-area">
      <KakaoMap />
    </div>

코드를 실행하면 지도가 정상 동작이 되고 있어서 추가 확인이 필요합니다.
스크린샷을 보면 ci와 축척이 여러번 겹쳐 올라간걸로 보아 지도를 여러번 생성하고 있는걸로 보여요.
지도는 최초 한 번만 생성되게 해주시고 렌더링 된 이후에 지도를 생성하고 있는지 다시 확인해주세요.

스크립트 2회 출력 되는 부분은 수정하여 지도 스크립트 2회 생성은 해결했습니다.
reactStrictMode: false

다만 렌더링 범위 이슈는 그대로 이네요.ㅠㅠ

    map.relayout(); 

이 코드로 해결되지 않으면 어떻게 해야할까요…?

깨지는 현상이 보이는 시점이 언제인가요?
지도 영역(width, height)이 잡히기 전에 지도를 생성하거나
지도 스타일 속성(display, width, height 등)이 동적으로 변경되었을 때 해당 현상이 보입니다.

지도를 생성하는 시점에 지도 영역(width, height)이 잡혔는지 확인해 주시고
동적으로 스타일이 변경되는 경우, 지도가 보이는 시점에 map.relayout()을 호출하고 있는지 확인 부탁드립니다.

그리고 지도가 표시되고 나서 버튼 또는 콘솔에서 map.relayout() 재호출 했을 때 정상적으로 표시된다면
map.relayout() 호출 시점을 변경해 주세요.

css 문제 확인하였고 div 크기가 동적으로 변하지 않아서

map.relayout();

코드도 제거하여도 정상 렌더링 됩니다!

정리

  1. 스크립트 모드 false
  2. css 수정
  3. map.relayout(); 제거

신경써서 답변 주셔서 감사합니다…

스스로 해결된 문제라 혹시라도 'lea.ju’님에 불필요한 시간소요를 줄여보고자 빠르게 답변을 달았는데…

아무쪼록 감사했습니다 :slight_smile:

2개의 좋아요