분명 APP Key도 잘 받아왔고, Map을 띄우는 코드도 잘 작성한 것 같은데 에러가 난다..?
이전에 포스팅으로 다뤘던 에러 사항에 더해 추가의 경우를 모아 새로 작성해 보려 한다.
TypeError: Cannot read properties of null (reading 'currentStyle')
App key를 받아 layout.tsx
에 Script
태그를 잘 적용했고, Map 객체를 불러오는 코드도 잘 작성했는데 위와 같은 오류가 만날 때이다.
'#2 지도 띄우기' 포스팅과 같이 Kakao Maps API를 활용한 지도 컴포넌트를 구현했고, MapProvider로 지도가 필요한 페이지마다 사용할 수 있도록 구현한 상태이다.
const MapProvider: React.FC<MapProps> = ({ children }) => {
const mapRef = useRef<HTMLDivElement>(null);
//...
useEffect(() => {
const { kakao } = window;
kakao?.maps.load(() => {
const mapElement = mapRef.current;
// 컴포넌트 mount 후 DOM 요소에 접근
if (mapElement) {
const options = {
center: new kakao.maps.LatLng(
location?.latitude as number,
location?.longitude as number,
),
level: 3,
smooth: true,
tileAnimation: false,
};
let zoomControl = new kakao.maps.ZoomControl();
// 지도 생성
const kakaoMap = new kakao.maps.Map(mapElement, options);
kakao.maps.event.addListener(kakaoMap, 'dragend', function () {
// 지도 중심좌표
const latlng = kakaoMap.getCenter();
setCurrLocation(latlng);
});
kakaoMap.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);
setMap(kakaoMap);
}
});
}, [location?.latitude, location?.longitude]);
//...
return (
<>
{location && (
<MapContext.Provider value={values}>
<div className='flex h-full w-full'>
{children}
<div id='map' ref={mapRef} className='h-full w-full'></div>
</div>
</MapContext.Provider>
)}
</>
);
};
export default MapProvider;
이 코드를 사용하여 지도를 렌더링하던 중, MapProvider가 포함된 현재 페이지에서 새로고침 또는 다른 MapProvider가 포함된 페이지로 이동할 때 위와 같은 TypeError 에러가 발생했다.
React 컴포넌트의 생명주기를 보면, 컴포넌트가 처음 마운트될 때 useEffect 훅이 실행되는데, 이 때 mapRef.current
가 null
일 수 있다.
즉, DOM 요소가 아직 마운트(생성)되지 않은 상태에서 해당 요소에 접근하려고 했기 때문에 에러가 발생한 것이다.
카카오 Dev 페이지 답변 - 카카오 api 사용 시 currentStyle null값 에러에 의하면, 여기서는 <div id = 'map'>
가 생성되지 않은 상태에서 #map
을 참조하려고 하기 때문에 발생한다.
해결을 위해서는 DOM 요소가 마운트된 후에 지도 생성 로직을 실행해야 힌다.
이를 위해 useEffect 내부에서 mapRef.current
가 null
이 아닌지 확인하는 조건문을 추가한다.
useEffect(() => {
const { kakao } = window;
kakao?.maps.load(() => {
const mapElement = mapRef.current;
// 컴포넌트 mount 후 DOM 요소에 접근
if (mapElement) {
const options = {
center: new kakao.maps.LatLng(
location?.latitude as number,
location?.longitude as number,
),
level: 3,
smooth: true,
tileAnimation: false,
};
let zoomControl = new kakao.maps.ZoomControl();
// 지도 생성
const kakaoMap = new kakao.maps.Map(mapElement, options);
kakao.maps.event.addListener(kakaoMap, 'dragend', function () {
// 지도 중심좌표
const latlng = kakaoMap.getCenter();
setCurrLocation(latlng);
});
kakaoMap.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);
setMap(kakaoMap);
}
});
}, [location?.latitude, location?.longitude]);
분명 지도가 띄워져야 할 자리에 흰 화면만 보인다..?
console 창에 에러도 안뜨는 상황이 당황스럽다면...
해당 문제가
- 배포 시
- 혹은 로컬에서
localhost:3000
이 아닌 다른 Port번호로 실행했을 때(3001
,3002
)
발생한다면 원인은 해당 프로젝트를 실행한 도메인에 있다.
이는 Kakao Developers에서 처음 App key를 발급하기 위해 생성했던 어플리케이션에 등록된 도메인과 다르기 때문이다.
도메인을 추가로 등록해 주어야 한다.
KaKao Developers 사이트에서 내 애플리케이션 > 앱 설정 > 플랫폼
에서 Web > 수정
버튼을 눌러 수정한다.
위와 같이 여러개의 도메인을 줄바꿈으로 추가 작성해 준다.
나는 포트번호가 다른 경우, 그리고 배포 URL을 함께 등록해 주었다.
⚠️
http://localhost:3000/
(x)
-> 도메인 끝에/
(슬래시)는 붙이면 안됨
해결!