ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Next.js에서 카카오 지도 사용하기
    개발공부/Next.js 2024. 1. 25. 20:45

    본 글을 Next.js에서 카카오 지도 오픈 API를 사용법을 다룬 내용입니다.

     

    결과물

     

    지도 만들기

    순서를 간단하게 요약하면 아래와 같다.

    1. 카카오 지도 Key 발급
    2. Next.tsx 파일 초기 설정
    3. 지도 그리기

     

    카카오 지도 Key 발급

    순서: 카카오 지도 페이지 접속 > 카카오로 로그인 > 내 애플리케이션 선택 > 애플르케이션 추가 및 선택 > JavaScript 키 복사

    (꼭 JavaScript 키 복사해두기!)

     

    Next.tsx 파일 초기 설정

    _document.tsx에서 카카오 지도 API 스크립트를 로드해야 한다!

    (해당 파일에서 스크립트를 로드하면 모든 페이지에 해당 스크립트가 포함되어 초기 로딩 시간 개선, 필요한 경우에만 API 활성화 가능)

     

    JavaScript 키는 아까 사이트에서 복사한 값 넣어주면 된다.

    import { Html, Head, Main, NextScript } from "next/document";
    import Script from "next/script";
    
    export default function Document() {
      return (
        <Html lang="en">
          <Head />
          <body>
            <Script
              strategy="beforeInteractive"
              src={`//dapi.kakao.com/v2/maps/sdk.js?appkey=${JavaScript 키}&libraries=services&autoload=false`}
            ></Script>
            <Main />
            <NextScript />
          </body>
        </Html>
      )
    }

     

    지도 그리기

    자, 이제 준비가 끝났으니 실제로 그려보자!

    import "react-kakao-maps-sdk";
    
    const KakaoMap = ({ location }: { location: string }) => {
    
    	// 1. 카카오 지도 초기화
        kakao.maps.load(() => {
        	// 2. 지도 생성 및 설정
            const container = document.getElementById("map");
            const options = {
                center: new kakao.maps.LatLng(33.450701, 126.570667),
                level: 3,
            };
            const map = new kakao.maps.Map(container as HTMLElement, options);
    
            let geocoder = new kakao.maps.services.Geocoder(); // 3. 주소-좌표 변환 객체 생성
            
            // 4. 지도 상에 주소를 표시
            geocoder.addressSearch(location, function(result, status) {
                if (status === kakao.maps.services.Status.OK) {
                	// 5. 결과값으로 받은 위치를 마커로 표시
                    const latitude: number = Number(result[0].y);
                    const longitude: number = Number(result[0].x);
    
                    let coords = new kakao.maps.LatLng(latitude, longitude);
                    let marker = new kakao.maps.Marker({
                        map: map,
                        position: coords
                    });
    
                    var infowindow = new kakao.maps.InfoWindow({
                        content: `<div style="width:300px;text-align:center;padding:6px 0;">${location}</div>`
                    });
                    infowindow.open(map, marker);
    
                    // 6. 지도의 중심을 결과값으로 받은 위치로 이동
                    map.setCenter(coords);
                }
            });
    
        });
    
        return (
            <div>
                <div className="flex items-center justify-center pt-2">
                    <div id="map" className="w-[95%] h-72" />
                </div>
            </div>
        )
    }
    
    export default KakaoMap;

     

    위 코드는 공식 문서를 참고해 작성했다.

    API 사용 방법이 간단하기도 하고, 공식 사이트에 사용 방법이 자세하게 나와있어 위의 코드를 짜는데 큰 어려움이 없었다.

     

    사실 여기까지 했을 때 '뭐, 별거 없네~?' 라고 생각했는데 그 생각은 페이지를 새로고침하고 바로 바뀌었다..ㅎ

     

    지도가 제대로 그려지는 거 확인하고 페이지를 새로고침했는데 아래 에러 문구가 콘솔에 찍히면서 화면에 아무것도 안보였다.. 껄껄

    에러 발생 (The above error occurred in the {컴포넌트 이름} component)

     

    이게 무슨 상황인지 찾아보니.. Next.js의 특징 때문이었다. 

    Next.js는 SSR을 수행하는데, 카카오 지도 SDK는 클라이언트 측 라이브러리여서 서버에서 로드되려고 할 때 해당 문제가 발생할 수 있다고 한다. 

     

    문제의 원인을 알고 나서 나는 바로 해결 방법을 찾았다. (왜냐? 최근에 비슷한 일을 겪었기 때문에...ㅎㅎ)


    이 문제를 해결하기 위해서는 카카오 지도 SDK가 클라이언트에 마운트될 때에만 라이브러리를 로드하도록 설정하면 된다.

    마운트될 때만 로드 하려면? 바로 useEffect 사용하면 된다!

     

    최종 코드

    import { useEffect } from "react";
    import "react-kakao-maps-sdk";
    
    const KakaoMap = ({ location }: { location: string }) => {
        useEffect(()=>{
        	// 1. 카카오 지도 초기화
            kakao.maps.load(() => {
            	// 2. 지도 생성 및 설정
                const container = document.getElementById("map");
                const options = {
                    center: new kakao.maps.LatLng(33.450701, 126.570667),
                    level: 3,
                };
                const map = new kakao.maps.Map(container as HTMLElement, options);
    
                let geocoder = new kakao.maps.services.Geocoder(); // 3. 주소-좌표 변환 객체 생성
    
    			// 4. 지도 상에 주소를 표시
                geocoder.addressSearch(location, function(result, status) {
                    if (status === kakao.maps.services.Status.OK) {
                        // 5. 결과값으로 받은 위치를 마커로 표시
                        const latitude: number = Number(result[0].y);
                        const longitude: number = Number(result[0].x);
    
                        let coords = new kakao.maps.LatLng(latitude, longitude);
    
                        // 결과값으로 받은 위치를 마커로 표시
                        let marker = new kakao.maps.Marker({
                            map: map,
                            position: coords
                        });
    
                        var infowindow = new kakao.maps.InfoWindow({
                            content: `<div style="width:300px;text-align:center;padding:6px 0;">${location}</div>`
                        });
                        infowindow.open(map, marker);
    
                        // 6. 지도의 중심을 결과값으로 받은 위치로 이동
                        map.setCenter(coords);
                    }
                });
            });
        }, [location]);
    
        return (
            <div>
                <div className="flex items-center justify-center pt-2">
                    <div id="map" className="w-[95%] h-72" />
                </div>
            </div>
        )
    }
    
    export default KakaoMap;

     

    728x90
Designed by Tistory.