도영스 공간
Next.js환경에서 카카오 맵 api 불러오기 본문
반응형
리액트에서 넥스트로 프로젝트를 변환하니까
맵이 안불러와지는 요상한 현상이 발생했다.
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ오잉?
오ㅐ..카카오 맵이 안불러와지지...?
구글링안하고,,
첫번째 방법
_document.tsx파일
import Document, { Html, Head, Main, NextScript } from "next/document";
export default class MyDocument extends Document {
render() {
return (
<Html>
<Head>
<link
rel="stylesheet"
as="style"
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.5/dist/web/static/pretendard.css"
/>
<Script
src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY를 넣으시면 됩니다.&libraries=services,clusterer&autoload=false"
strategy="beforeInteractive"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
실제 map을 불러오는 코드가 있는 부분
/*global kakao*/
import React, { useEffect, useState } from "react";
import styled from "styled-components";
declare global {
interface Window {
kakao: any;
}
}
const { kakao } = window;
const MainMap = (): React.ReactElement => {
const [level, setLevel] = useState(8); //지도레벨
const [pos, setPos] = useState(); //경도 위도
useEffect(() => {
let container = document.getElementById("map");
let options = {
center: new kakao.maps.LatLng(37.5173319258532, 127.047377408384),
level: level,
};
let map = new kakao.maps.Map(container, options);
}, []);
const setLocation = () => {
let container = document.getElementById("map");
let options = {
center: new kakao.maps.LatLng(37.5173319258532, 127.047377408384),
level: level,
};
let map = new kakao.maps.Map(container, options);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
let lat = position.coords.latitude, // 위도
lon = position.coords.longitude; // 경도
let locPosition = new kakao.maps.LatLng(lat, lon);
map.setCenter(locPosition);
});
}
};
//줌인
const zoomIn = () => {
if(level>5){
setLevel(level - 1);
}
let container = document.getElementById("map");
let options = {
center: new kakao.maps.LatLng(37.5173319258532, 127.047377408384),
level: level,
};
let map = new kakao.maps.Map(container, options);
};
//줌아웃
const zoomOut = () => {
if(level<10){
setLevel(level + 1);
}
let container = document.getElementById("map");
let options = {
center: new kakao.maps.LatLng(37.5173319258532, 127.047377408384),
level: level,
};
let map = new kakao.maps.Map(container, options);
};
return (
<React.Fragment>
<MapWrap id="map"></MapWrap>
<MainContent>
<Lev>
<Btn onClick={setLocation}>
<Location />
</Btn>
<PlusBtn>
<button onClick={zoomIn}>
<Plus />
</button>
<button onClick={zoomOut}>
<Minus />
</button>
</PlusBtn>
</Lev>
</MainContent>
</React.Fragment>
);
};
const MapWrap = styled.div`
width: 100%;
height: 100vh;
`;
const MainContent = styled.div`
position: absolute;
width: 100%;
height:90%;
top:0;
left:0;
`;
const Lev = styled.div`
width: 40px;
height: 125px;
position: absolute;
bottom: 5%;
left: 16px;
z-index: 2;
display: flex;
flex-direction: column;
gap: 5px;
`;
const Btn = styled.button`
width: 40px;
height: 40px;
background: #fff;
border: none;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.1);
`;
const PlusBtn = styled.div`
width: 40px;
height: 72px;
background: #fff;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.1);
position: relative;
&::before {
content: "";
display: block;
width: 24px;
height: 1px;
background-color: ${({ theme }) => theme.colors.darkgray2};
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 3;
}
& button {
background: none;
border-radius: 0px;
width: 30px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
}
`;
export default MainMap;
=> 실패 흰 화면만 뜬당...
ㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜ
구글링 후
두번째 방법 시도
_document.tsx파일에 넣었던 script는 없앤다...
지도를 불러오는 파일
/*global kakao*/
import React, { useEffect, useState, useRef, useCallback } from 'react';
import Head from 'next/head';
import Script from 'next/script';
import styled from 'styled-components';
//아이콘
import { Spinner } from '../../shared/index';
import Minus from '../../../../public/assets/minus.svg';
import Plus from '../../../../public/assets/plus.svg';
import Location from '../../../../public/assets/location.svg';
declare global {
interface Window {
kakao: any;
}
}
const NEXT_PUBLIC_KAKAO_KEY = process.env.NEXT_PUBLIC_KAKAO_KEY;
const MainMap = (): React.ReactElement | null => {
const [level, setLevel] = useState(8); //지도레벨
const [pos, setPos] = useState(); //경도 위도
const containerRef = useRef<HTMLDivElement>(null); // 지도 ref
//map불러오기
const initMap = useCallback(() => {
if (containerRef.current) {
const map = new kakao.maps.Map(containerRef.current, {
center: new kakao.maps.LatLng(37.5173319258532, 127.047377408384),
level: level,
});
}
}, []);
useEffect(() => {
if (window?.kakao) {
initMap();
}
}, [initMap]);
//나의 위치로 가게 해주는 함수
const setLocation = () => {
let container: any = document.getElementById('map');
let options = {
center: new kakao.maps.LatLng(37.5173319258532, 127.047377408384),
level: level,
};
let map = new kakao.maps.Map(container, options);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
let lat = position.coords.latitude, // 위도
lon = position.coords.longitude; // 경도
let locPosition = new kakao.maps.LatLng(lat, lon);
map.setCenter(locPosition);
});
}
};
//줌인
const zoomIn = () => {
if (level > 5) {
setLevel(level - 1);
}
let container: any = document.getElementById('map');
let options = {
center: new kakao.maps.LatLng(37.5173319258532, 127.047377408384),
level: level,
};
let map = new kakao.maps.Map(container, options);
};
//줌아웃
const zoomOut = () => {
if (level < 10) {
setLevel(level + 1);
}
let container: any = document.getElementById('map');
let options = {
center: new kakao.maps.LatLng(37.5173319258532, 127.047377408384),
level: level,
};
let map = new kakao.maps.Map(container, options);
};
return (
<React.Fragment>
<Script
src={`https://dapi.kakao.com/v2/maps/sdk.js?appkey=${NEXT_PUBLIC_KAKAO_KEY}&autoload=false`}
onLoad={() => kakao.maps.load(initMap)}
/>
<Head>
<link rel='preconnect' href='https://dapi.kakao.com' />
<link rel='dns-prefetch' href='https://dapi.kakao.com' />
</Head>
<MapWrap id='map' ref={containerRef}></MapWrap>
<MainContent>
{is_loaded ? null : <Spinner />}
<Lev>
<Btn onClick={setLocation}>
<Location />
</Btn>
<PlusBtn>
<button onClick={zoomIn}>
<Plus />
</button>
<button onClick={zoomOut}>
<Minus />
</button>
</PlusBtn>
</Lev>
</MainContent>
</React.Fragment>
);
};
const MapWrap = styled.div`
width: 100%;
height: 100vh;
`;
const MainContent = styled.div`
position: absolute;
width: 100%;
height: 90%;
top: 0;
left: 0;
`;
const Lev = styled.div`
width: 40px;
height: 125px;
position: absolute;
bottom: 5%;
left: 16px;
z-index: 2;
display: flex;
flex-direction: column;
gap: 5px;
`;
const Btn = styled.button`
width: 40px;
height: 40px;
background: #fff;
border: none;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.1);
`;
const PlusBtn = styled.div`
width: 40px;
height: 72px;
background: #fff;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.1);
position: relative;
&::before {
content: '';
display: block;
width: 24px;
height: 1px;
background-color: ${({ theme }) => theme.colors.darkgray2};
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 3;
}
& button {
background: none;
border-radius: 0px;
width: 30px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
}
`;
export default MainMap;
짜짠..넥스트에서 잘 불러와져따 !!!
.env파일을 만들어서 자바스크립트 키를 적으면 된다 !!!
끗...
넥스트 어렵당 ... ;
728x90
반응형
'TIL > 2022 TIL' 카테고리의 다른 글
스택과 큐 (1) | 2022.07.25 |
---|---|
REST API(Representational State Transfer) (1) | 2022.07.21 |
Recursion 재귀함수 (0) | 2022.07.12 |
자바스크립트 Array 고차함수 정리 2(sort / some/ every /find /findIndex) (0) | 2022.07.06 |
자바스크립트 Array 고차함수 정리 1 (forEach / map/ filter /concat /reduce) (0) | 2022.07.05 |
Comments