React.js

KakaoMap UX 향상시키기 - API 문서를 잘 읽자!

ImJaeOne 2025. 2. 28. 12:06

1. 기존 UX의 문제점

일반적으로 지도에서 여러 개의 마커를 표시하면 사용자가 특정 상품을 클릭해도 지도 위치는 변하지 않으며, 사용자가 해당 상품의 위치를 명확하게 인지하기 어렵다고 생각되었습니다.
즉, 상품을 클릭했을 때 해당 상품을 중심으로 지도 이동이 이루어지지 않으면 UX가 저하될 수 있습니다.

 

2. UX 개선 방법

상품을 클릭하면:

  1. 해당 상품의 위치를 지도 중심(center)으로 이동
  2. 해당 상품의 정보를 커스텀 오버레이(CustomOverlayMap)로 표시
  3. 지도를 클릭하면 오버레이가 닫히도록 설정

이를 통해 사용자는 특정 상품을 클릭할 때마다 그 상품이 화면의 중앙에 위치하면서 관련 정보를 즉시 확인할 수 있습니다.

 

3. 구현 과정

3.1 상태관리

const [location, setLocation] = useState({ lat: null, lng: null }); 
const [productInfo, setProductInfo] = useState(null);
const [center, setCenter] = useState(location);

 

  • location: 초기 사용자의 중심을 관리하는 상태 - 화면의 첫 렌더링 시 사용자의 위치를 지정하는 역할을 합니다.

  • center: 지도의 중심을 관리하는 상태
  • productInfo: 현재 선택된 상품의 정보를 저장하는 상태

3.2. 선택한 상품의 중심 이동 및 오버레이 표시

useEffect(() => {
  if (selectedProduct) {
    const foundProduct = productList.find(
      (product) => product.id === selectedProduct
    );
    if (foundProduct) {
      setCenter(foundProduct.location); 
    }
    setProductInfo(foundProduct || null);
  }
}, [selectedProduct, productList]);
  • selectedProduct가 변경될 때마다 productList에서 해당 상품을 찾아 center를 업데이트하여 지도 중심을 변경합니다.
  • productInfo를 업데이트하여 해당 상품에 대한 오버레이가 나타나도록 설정합니다.(이 부분은 최종 코드를 보시면 이해가 되실겁니다.)

3.3. 최종 코드

{productInfo && productInfo.id === product.id && (
  <CustomOverlayMap position={product.location} yAnchor={1.4} clickable={true}>
    {/* 상품 정보 표시 */}
  </CustomOverlayMap>
)}
  • productInfo가 존재할 때만 오버레이를 렌더링 (즉, 상품이 선택되지 않았으면 아무것도 표시되지 않음) 
    • 위 코드에서 사용자가 선택한 물품이 있을 경우 setProduct를 한 이유입니다.
  • productInfo.id === product.id → 현재 반복문에서 렌더링 중인 product와 선택된 productInfo가 같을 때만 해당 마커에 오버레이를 표시합니다.

 

이렇게 잘 마무리되나 싶었지만... 어김 없이 문제가 발생했습니다....

에러 그만.....

🛑  CustomOverlayMap에 클릭 이벤트 적용이 안된다...?

CustomOverlayMap을 편하게 박스라고 부르겠습니다.

<CustomOverlayMap position={product.location} yAnchor={1.4}>
      <Link to={`/product/detail?id=${product.id}`}>
      {/*CustomOverlay*/}
      </Link>
</CustomOverlayMap>

 

박스를 누르면 물품 상세 페이지로 이동해야합니다.

하지만 페이지를 이동하지도 않고 박스가 닫히는 문제가 발생하였습니다.

e.stopPropagation()을 사용해 Map의 이벤트가 발생하지 않도록 방지

상위의 Map의 이벤트가 발생이 되어서 Link가 동작하지 않는 것이라 생각하여 e.stopPropagation()을 이용해봤습니다.

<CustomOverlayMap position={product.location} yAnchor={1.4} onClick={() => e.stopPropagation()}>
      {/*CustomOverlay*/}
</CustomOverlayMap>

하지만 똑같은 문제가 발생하였습니다.

그래서 클릭 이벤트 자체가 발생하지 않나? 라는 생각이 들어 console을 출력해보았습니다.

<CustomOverlayMap position={product.location} yAnchor={1.4} onClick={() => console.log(1)}>
      {/*CustomOverlay*/}
</CustomOverlayMap>

console 자체가 출력되지 않습니다.

 

clickable={true}로 CustomOverlayMap의 클릭 이벤트 허용

박스의 z-index를 조절도 해봤지만 그 방식도 아니었습니다.

그래서 공식 문서를 하나씩 읽어 봤는데

clickable={true} // 마커를 클릭했을 때 지도의 클릭 이벤트가 발생하지 않도록 설정합니다

넵 이렇게 사용하라고 명시가 되어 있었습니다.

 

마커에 클릭 이벤트 등록하기 | react-kakao-maps-sdk docs

마커를 마우스로 클릭했을때 click 이벤트가 발생합니다. 이 예제에서는 마커를 클릭했을 때 마커 위에 인포윈도우를 표시하고 있습니다.

react-kakao-maps-sdk.jaeseokim.dev

<CustomOverlayMap position={product.location} yAnchor={1.4} clickable={true}>
      {/*CustomOverlay*/}
</CustomOverlayMap>

 

오늘의 교훈

문제가 생기면 공식 문서부터 읽자~~ 사소한 속성이지만, 의도적으로 막혀있는 기능이 있을 수 있다~~~