✔️ 카카오 맵 구현
- 카카오 아이디를 이용해 로그인
- 내 애플리케이션(내 프로젝트만들기)
- 내앱 -> 플랫폼 -> 사이트도메인 등록하기
- 제품 -> 지도/로컬 -> 문서보기 -> mapsAPI
- 어떤 브라우저에서 카카오 맵 API를 사용할 건지 선택
- [ 키 발급 ] 발급 페이지에서 key확인
- Guide 페이지 이동
- [ 지도를 띄우는 코드 작성 ]
- 용도에 맞는 키를 사용해서 넣기
JavaScript API Key와 같은 민감 정보를 github에 올려도 될까?
안됨❗️❗️❗️❗️❗️❗️env를 이용한 환경변수 설정 등의 방법 등으로 최대한 숨겨주고,
절대 노출되면 안되는 중요 민감 정보의 경우에는프론트엔드 서버에 두지 말고 백엔드 서버에 놓고 사용하는 편
이 안전하다.
가이드라인은 바닐라 (Original) JavaScript와 HTML 기준으로 만들어진 코드이다.
React 에서,
특히 Next JS
에서는HTML에 접근할 수 있는 방법이 한정적
이기 때문에 가이드라인 만으로는 구현할 수 없다.가이드라인 속 document 객체는
서버사이드 렌더링을 지원하는 Next.js 에서, 화면을 렌더하기 전까지생성되지 않은 값 (=undefiend)
을 가진다.따라서 그대로 입력 시 오류가 발생함!
[실습 section25]
- index.tsx
export default function KakaoMapPage(): JSX.Element { const router = useRouter(); const onClickMove = (): void => { void router.push("/section25/25-02-kakao-map-routing-moved"); }; return ( <button onClick={onClickMove}>페이지이동</button> ) }
- rounting page
import { useEffect } from "react"; declare const window: typeof globalThis & { kakao: any; }; export default function KakaoMapPage(): JSX.Element { useEffect(() => { 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); //지도 생성 및 객체 리턴 }, []); return ( <> <script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY를 넣으시면 됩니다." </script> <div id="map" style={{ width: 500, height: 400 }}></div> </> ); }
프론트엔드 서버에서 페이지가 그려지는 시점에는
document 가 undefined 한 값
을 가지고 있다.(서버사이드 렌더링의 특징 중 하나)document 를 사용하는 시점을
document 가 생성된 시점 이후
로 변경해주기 위해
useEffect
를 이용해 페이지가 마운트되고
document 객체가 생성된 이후에 카카오맵을 호출할 수 있도록 변경해준다.그러나
kakao를 찾을 수 없다며 에러가 뜬다.
만약 router를 사용하지 않고 a 태그를 이용하여 페이지를 이동해본다면?
아무런 문제 없이 지도가 출력되는 것을 확인할 수 있다.
이와 같은 현상을 이해하기 위해서는 싱글페이지 어플리케이션에 대한 이해가 필요하다.
1️⃣ router
SPA(Single Page Application)
: router를 이용해서 페이지를 이동하는 것과 같은 방식을 채택하는 웹 서비스로,
홈페이지보다 애플리케이션 의 느낌이 강하다.SPA에서는 서비스에 처음 접속할 때 모든 페이지의 데이터를 다 받아온다.
그리고 router를 통해 페이지를 이동할 때, 실제로는 페이지의 일부에 해당하는 컴포넌트만 교체한 뒤 페이지를 다시 그려오게 된다.
(re-rendering)
SPA의 경우 최초 로딩에는 시간이 다소 걸릴 수 있으나 페이지를 이동할 때 걸리는 시간이 MPA에 비하여 압도적으로 짧다.
2️⃣ a 태그
MPA(Multi Page Application)
: a 태그를 이용해서 페이지를 이동하는 것과 같은 방식을 채택하는 웹 서비스로,
전통적인 의미의 홈페이지!MPA에서 서로 다른 url을 가진 페이지들은 각각 독립적으로 존재하기 때문에,
프론트엔드 서버에서 페이지를 그린 뒤 브라우저로 HTML/CSS/JS를 보내주는 작업을
매 페이지 이동 시마다 거치게 된다.
주소를 직접 입력해서 들어가는 것과 a태그를 통해 페이지를 이동하는 것은 본질적으로 동일하다.하지만 MPA 의 경우,
페이지 이동 시마다 서버에 요청해서 데이터를 받아와야 하기 때문에 성능은 좋지 않다.a 태그를 이용하면 오류는 해결되지만, 페이지를 이동했을 때 페이지 자체가 새로 로딩되기 때문에
SPA 프레임워크인 Next.js를 사용하는 의미가 없어진다.3️⃣ Next.js의 Link 태그 활용
- index.tsx
import Link from "next/link"; import { useRouter } from "next/router"; export default function KakaoMapPage(): JSX.Element { const router = useRouter(); const onClickMove = (): void => { void router.push("/section25/25-02-kakao-map-routing-moved"); }; return ( <> <button onClick={onClickMove}>페이지이동</button> {/* 매 페이지를 새로 다운로드 받으므로 SPA를 활용 불가*/} <a href="/section25/25-02-kakao-map-routing-moved"> 페이지이동2</a> {/* next에서 제공하는 a태그 이므로 , SPA도 활용 가능 + <a>를 써서 검색엔진 최적화성능높임(SEO) - 빠른 속도로 이동*/} <Link href="/section25/25-02-kakao-map-routing-moved">페이지이동3</Link> {/* 의미가 있는 시맨틱 태그의 장점 */} <h1>tag</h1> <div>tag</div> <section>tag</section> </> ); }
3가지 버전 속도비교
- routung.page
import { useEffect } from "react"; declare const window: typeof globalThis & { kakao: any; }; export default function KakaoMapPage(): JSX.Element { useEffect(() => { // 2번 방법 : 여기서 직접 다운로드 받고, 다 받을때까지 기다렸다가 그려주기!! const script = document.createElement("script"); //<script>태그 만들기 script.src ="//dapi.kakao.com/v2/maps/sdk.js?autoload=false&appkey=발급받은 key"; //query string : &로 연결! document.head.appendChild(script); script.onload = () => { window.kakao.maps.load(function () { 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); //지도 생성 및 객체 리턴 console.log(map); }
- routung.page
import { useEffect } from "react"; declare const window: typeof globalThis & { kakao: any; }; export default function KakaoMapPage(): JSX.Element { useEffect(() => { // 2번 방법 const script = document.createElement("script"); //<script>태그 만들기 script.src = "//dapi.kakao.com/v2/maps/sdk.js?autoload=false&appkey=발급받은 key"; document.head.appendChild(script); script.onload = () => { window.kakao.maps.load(function () { 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); //지도 생성 및 객체 리턴 console.log(map); // 마커가 표시될 위치입니다 const markerPosition = new window.kakao.maps.LatLng( 33.450701, 126.570667 ); // 마커를 생성합니다 const marker = new window.kakao.maps.Marker({ position: markerPosition, }); // 마커가 지도 위에 표시되도록 설정합니다 marker.setMap(map); }); }; }, []); return ( <> {/* 1번방법 */} {/* <script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 key" </script> */} <div id="map" style={{ width: 500, height: 400 }}></div> </> ); }
마커찍는 법
샘플 -> 오버레이 -> 마커생성하기
검색 엔진 최적화를 위해서는 Link 태그가 더 적합하다!
Link는 클릭하자마자 바로 넘어가기 때문에,
클릭하고 로직을 처리하고 이동을 해야하는 상황에서는 사용하지 못한다.
Link태그를 못사용할 때 router.push를 쓴다.
- software development kit 지도 라이브러리
- this는 곧 window 전역this라고도 함
글로벌 this
window안에 kakao가 임시적으로 생기게 됨