[Kakao map] 지도

이주희·2023년 6월 10일
1
post-custom-banner

각각의 서비스가 제공해주는 오픈 api가 있다.

지도 API 선택 tip

하루에 API를 무료로 요청할 수 있는 횟수에 제한이 있다.
구글은 횟수 제한이 낮아서 카카오를 더 선호하고, 해외 지도도 필요할 경우에 구글맵을 사용한다.
지도를 보여주는 것뿐만 아니라 다른 기능도 필요할 경우, 제공하는 기능에 따라서 네이버 혹은 카카오를 선택한다.
카카오는 카카오 네비 연동이 가능하다.


Kakao map 이용 방법

[kakaomap API guide]

  1. 카카오 개발자사이트 (https://developers.kakao.com) 접속
  2. 개발자 등록 및 앱 생성
  3. 웹 플랫폼 추가: 앱 선택 – [플랫폼] – [Web 플랫폼 등록] – 사이트 도메인 등록
  4. 사이트 도메인 등록: [웹] 플랫폼을 선택하고, [사이트 도메인] 을 등록합니다. (예: http://localhost:8080)
  5. 페이지 상단의 [JavaScript 키]를 지도 API의 appkey로 사용합니다.
  6. 앱을 실행합니다.

1. 내 애플리케이션 > 애플리케이션 추가하기

다른 서비스에서는 내 앱이라고 적혀있는 경우도 있다.
각 애플리케이션을 프로젝트의 폴더라고 생각하면 된다.

2. 생성한 앱 선택 > 플랫폼 설정하기 > Web

⭐️배포 시 도메인 변경을 잊지 말자⭐️

등록 완료

가이드에 나와있는 순서대로 진행하면 된다.

3. 내 애플리케이션 > 생성한 앱 선택 > 앱 키의 JS 키 복사

4. return에 지도를 추가할 jsx 생성

<div id="map" style={{width:500, height:400}}></div>

5. return에 script 추가

script 태그를 사용하기 위해 'next/head'의 Head를 import 받아서 그 안에 넣는다.

3에서 복사한 앱 키를 발급받은 APP KEY를 넣으시면 됩니다. 부분에 넣는다.

import Head from 'next/head'

<Head>
        <script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=92958565365b230a39d7a23849c34582"></script>
</Head>

6. 지도를 띄우는 코드 작성


이 코드를 가져와서 react에서 사용할 수 있게 수정한다.

declare를 추가하고
kakao를 찾을 수 있게 window.kakao로 변경

declare const window: typeof globalThis & {
    kakao:any;
}
useEffect(() => {
    // map이 만들어진 이후에 실행
    const container = document.getElementById("map"); // 지도를 담을 영역의 DOM 레퍼런스
    const options = {
      // 지도를 생성할 때 필요한 기본 옵션
      center: new window.kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표.
      level: 3, // 지도의 레벨(확대, 축소 정도)
    };

    const map = new window.kakao.maps.Map(container, options); // 지도 생성 및 객체 리턴 : 담아도 되고 안 담아도 된다.
  }, []);

끗!


routing & routed

지도가 있는 화면에 엔터를 눌러서 진입할 때와 버튼을 눌러서 진입할 때의 차이

🚨 Error!

  • 다른 페이지에서 카카오맵이 있는 링크로 버튼을 눌러서 이동하면 maps를 찾을 수 없다는 오류가 나온다.
  • a태그로 진입하면 잘 나온다.
  • 카카오맵이 있는 url에서 새로고침을 하면 잘 나온다!

Client side Rendering / Single Page Application

Multi Page Application

a태그(anchor 태그)로 페이지 이동
브라우저에서 주소를 입력해서 접속하면 프론트엔드 서버에 접속하고 html,css,js를 받아와서 브라우저에 화면이 그려진다.
브라우저에서 a태그를 통해 다른 페이지로 이동하면 마찬가지로 프론트엔드에 접속해서 다른 페이지에 대한 html,css,js를 받아와서 화면이 그려진다.
새로고침을 했을 때도 동일하다.
속도가 느리다는 단점이 있다.

Single Page Application

react, angular, vue는 Single Page Application이라고 부른다.
Singlt Page Application
브라우저에서 주소를 입력해서 들어오면, 프론트 서버에 접속해서 html, css, js를 받아올 때 한 페이지만 받아오는 것이 아니라
전체 페이지를 다 받아서 온다.
페이지 이동 시 html, css, js를 다시 받아오는 것이 아니라 처음에 받아온 것에서 이동한다.(Client Side Rendering: 서버에 가지 않고, 브라우저에서 화면을 변경)
거대한 한 페이지 안에서 이동한다고 해서 Single Page Application
페이지를 매번 새로 받아오는 과정이 없기 때문에 속도가 매우 빠르다.

  • router는 react에서 제공해주는 페이지 이동으로, Single Page Application에서 Client Side Rendering을 하게 된다.
  • a태그는 페이지를 새로 다운받아온다.

Client Side Rendering

router.push 말고 태그를 클릭해서 이동하는 방법
(-> 얘도 로드되기 전에 실행되므로 kakao를 찾지 못한다는 에러가 뜬다.)

import Link from 'next/link'

return(
  <Link href="/29-03-kakao-map-routed">
  	<a>Link: 맵으로 이동하기</a>
  </Link>
  )

<Link>가 더 좋다!
태그들만의 기능이 있다.
Link 태그는 a 태그로 바뀌어서 움직여야 한다.
a태그를 쓰면 Client Side Rendering이 안된다. 페이지를 새로 다운받아서 준다.
CSR을 원하면 router.push나 Link 태그를 사용해야 한다.

시맨틱 태그

Link 태그를 사용할 때는 안에 a태그로 감싸준다.
(가짜 a태그이다. 그럼 왜해? ->
검색 봇이 다른 사이트를 돌아다니면서 접속해서 html, css, js를 다운로드 받아서 분석을 한다. 어떤 사이트인지 분석을 하는데, 검색봇과 소통을 하는 창구가 태그이다. 눈으로 볼 때는 똑같지만, 검색봇이 볼 때는 h1과 div를 다르게 인식한다. 태그의 의미는 중요하다. css를 활용하면 똑같이 보여줄 수 있지만, 태그로 의미를 부여하는 것이 매우 중요하다.)
a 태그가 붙어있으면 페이지 이동이라는 것을 검색봇이 인식할 수 있다.

router.push는 링크를 사용할 수 없을 때 사용한다. 예를 들면 게시물 작성 후 상세 화면으로 이동할 경우!

CSR은 처음에만 서버에서 받아오고 그 이후에는 서버에서 받아오지 않는다. 빠르다.
CSR이 아닌 경우에는 매번 서버에서 받아와서 느리다.

💡 Why?

위 경우에서 script를 받아오기 전에 페이지가 이미 존재하고, useEffect가 실행되어버리기 때문에 kakao를 찾지 못하는 것이다.

해결 방법 1. script 자체를 미리 다운 받아놓기

_app.tsx에 script를 받는다.

당연히 좋은 방법은 아니다. 맵을 사용하지 않는 페이지에서도 카카오맵을 다운받기 때문에 비효율적이다.

해결 방법 2. 다운로드 받을 때까지 기다리기 👍🏻


key 뒤에 &autoload=false 추가한다
쿼리스트링: 주소로 객체를 보낼 때
객체의 키가 두개인 형태로 전송된다.

import { useEffect } from "react";

declare const window: typeof globalThis & {
  kakao: any;
};

export default function KakaoMapPage() {
  useEffect(() => {
    const script = document.createElement("script"); // <script></script>
    script.src =
      "//dapi.kakao.com/v2/maps/sdk.js?appkey=92958565365b230a39d7a23849c34582&autoload=false"; // 카카오맵이 로드되면 실행
    document.head.appendChild(script); // header에 script를 자식으로 추가한다.
      
    // script가 로드되면 실행
    script.onload = () => {
       // kakaomap이 로드되면 실행
      window.kakao.maps.load(function () {
        const container = document.getElementById("map"); 
        const options = {
          center: new window.kakao.maps.LatLng(33.450701, 126.570667), 
          level: 3,
        };
        const map = new window.kakao.maps.Map(container, options);
      });
    };
  }, []);

  return (
    <>
      <div id="map" style={{ width: 500, height: 400 }}></div>
    </>
  );
}
profile
🍓e-juhee.tistory.com 👈🏻 이사중
post-custom-banner

0개의 댓글