클릭한 마커에 대한 장소 상세정보를 커스텀 오버레이로 표시하는 함수에 관한 질문을 드립니다

// 클릭한 마커에 대한 장소 상세정보를 커스텀 오버레이로 표시하는 함수입니다
function displayPlaceInfo (place) {
    var content = '<div class="placeinfo">' +
                    '   <a class="title" href="' + place.place_url + '" target="_blank" title="' + place.place_name + '">' + place.place_name + '</a>';   

    if (place.road_address_name) {
        content += '    <span title="' + place.road_address_name + '">' + place.road_address_name + '</span>' +
                    '  <span class="jibun" title="' + place.address_name + '">(지번 : ' + place.address_name + ')</span>';
    }  else {
        content += '    <span title="' + place.address_name + '">' + place.address_name + '</span>';
    }                
   
    content += '    <span class="tel">' + place.phone + '</span>' + 
                '</div>' + 
                '<div class="after"></div>';

    contentNode.innerHTML = content;
    placeOverlay.setPosition(new kakao.maps.LatLng(place.y, place.x));
    placeOverlay.setMap(map);  
}

이것처럼 하면 코드가 지저분해지고 그래서 코드를 컴포넌트화를 했습니다.

// 마커 클릭 시 장소 정보를 표시하는 커스텀 오버레이를 표시하는 함수
    const displayPlaceInfo = (place) => {
      const overlayContent = document.createElement('div');

      const root = createRoot(overlayContent);
      root.render(<PlaceOverlay place={place} id="closeOverlay" />);

      // 오버레이 설정
      placeOverlay.setContent(overlayContent);
      placeOverlay.setPosition(new window.kakao.maps.LatLng(place.y, place.x));
      placeOverlay.setMap(map);

      // 오버레이 닫기 버튼 이벤트
      const closeOverlayBtn = overlayContent.querySelector('#closeOverlay');
      if (closeOverlayBtn) {
        closeOverlayBtn.addEventListener('click', () => {
          placeOverlay.setMap(null);
        });
      }

      // 지도 클릭 시 오버레이 닫기
      window.kakao.maps.event.addListener(map, 'click', () => {
        placeOverlay.setMap(null);
      });
    };

위 코드는 커스텀 오버레이를 표시하는 함수입니다.

import React, { useState } from 'react';

import propTypes from 'prop-types';

import ModalPortal from '../modal/modal-portal';
import Modal from '../modal/modal';
import { FaRegWindowClose } from 'react-icons/fa';

function PlaceOverlay({ place, id }) {
  const [isModalOpen, setIsModalOpen] = useState(false);

  const handleOpenModal = () => {
    setIsModalOpen(true);
    console.log('모달 오픈');
  };

  const handleCloseModal = () => {
    setIsModalOpen(false);
  };

  return (
    <>
      <div className="absolute animate-fadein rounded-lg border border-gray-300 bg-white shadow-md">
        <div className="rounded-t-md bg-red-500 px-4 pb-2 pt-3 font-bold text-white">
          <button
            onClick={handleOpenModal}
            className="px-6 hover:text-blue-300 hover:underline"
          >
            {place.place_name}
          </button>
          <button
            id={id}
            className="absolute right-2 top-2 text-white hover:text-orange-300"
          >
            <FaRegWindowClose size={23} />
          </button>
        </div>
        <div className="p-4">
          {place.road_address_name ? (
            <div title={place.road_address_name} className="text-sm">
              {place.road_address_name}
            </div>
          ) : (
            ''
          )}

          {place.address_name ? (
            <div title={place.address_name} className="text-sm">
              (지번 : {place.address_name})
            </div>
          ) : (
            ''
          )}
          <div className="text-sm text-green-600">{place.phone}</div>
        </div>
      </div>
      {isModalOpen && (
        <ModalPortal>
          <Modal onClose={handleCloseModal}>
            <h1 className="mb-4 text-center text-2xl font-bold">
              {place.place_name}
            </h1>
            <div className="mb-4">
              <img
                src={place.place_image}
                alt={place.place_name}
                className="h-96 w-full rounded-lg object-cover"
              />
            </div>
            <div className="text-sm text-gray-600">
              {place.category_group_name}
            </div>
            <div className="text-sm text-gray-600">{place.category_name}</div>
            <div className="text-sm text-gray-600">{place.phone}</div>
            <div className="text-sm text-gray-600">{place.address_name}</div>
            <div className="text-sm text-gray-600">
              {place.road_address_name}
            </div>
            <div className="text-sm text-gray-600">{place.place_url}</div>
          </Modal>
        </ModalPortal>
      )}
    </>
  );
}

PlaceOverlay.propTypes = {
  place: propTypes.object,
  id: propTypes.string,
};

export default PlaceOverlay;

위 코드는 커스텀 오버레이 코드입니다.

여기서 모달을 열기 위한 버튼을 클릭하면 콘솔창에 '모달 오픈’도 찍히지 않고 모달이 그냥 바로 꺼져버립니다.

무엇이 문제인지 모르겠습니다. ㅜㅜ 참고로 Modal, ModalPortal은 이상이 없으며, index.html에도 레이아웃을 따로 분리하였습니다.

처음에는 ReactDOMServer.toRendertoString 을 통해서 innerHTML로 작성되도록 하였는데 찾아보니 상태관리와 같은 것은 인식을 못한다고 합니다. 그래서 createRoot를 통해서 시도를 해보았지만 안돼서 글을 작성해봅니다… ㅠ

CustomOverlay 컨텐츠 영역을 클릭할 때 지도 이벤트까지 전파되서 지도 클릭 이벤트가 실행된 걸로 보입니다.
그래서 handleOpenModal이 실행되는 버튼을 눌렀지만 CusomOverlay가 닫혀서 동작되지 않은 것처럼 보이는 것 같아요.
CustomOverlay의 clickable 속성을 true로 설정해서 확인해주세요.

const placeOverlay = new kakao.maps.CustomOverlay({clickable: true});