Suspense & 스크립트 로딩
동작 방식
react-naver-maps는 React 19의 use()를 사용하여 네이버맵 스크립트를 로드합니다.
useNavermaps() 훅이 호출되면 스크립트 로드 Promise를 use()로 감싸서, 로드가 완료될 때까지 컴포넌트를 suspend합니다.
Container의 내장 Suspense
<Container>는 내부에 <Suspense>를 포함하고 있으므로, 별도로 감쌀 필요가 없습니다.
// Container 안에서는 Suspense 불필요
<Container style={{ width: '100%', height: '400px' }}>
<NaverMap /> {/* 내부에서 useNavermaps() 호출 */}
</Container>
fallback prop으로 로딩 UI를 지정할 수 있습니다.
<Container
style={{ width: '100%', height: '400px' }}
fallback={<div>지도를 불러오는 중...</div>}
>
<NaverMap />
</Container>
SSR / 정적 빌드와 함께 사용
react-naver-maps는 SSR 환경을 지원합니다. 서버에서는 네이버맵 스크립트를 로드할 수 없으므로, <Container>의 외부 div(높이 포함)만 렌더링되고 내부 지도는 클라이언트에서 hydration 후 표시됩니다.
이 동작이 올바르게 작동하려면 useNavermaps()를 반드시 <Container> 안에서 호출해야 합니다. Container의 내장 Suspense가 스크립트 로딩을 처리합니다.
// ✅ 올바른 구조 — useNavermaps()가 Container 안
function MyMap() {
return (
<Container style={{ width: '100%', height: '400px' }}>
<MapContent />
</Container>
);
}
function MapContent() {
const navermaps = useNavermaps();
return (
<NaverMap
defaultCenter={new navermaps.LatLng(37.5666, 126.9784)}
defaultZoom={15}
/>
);
}
// ❌ 잘못된 구조 — useNavermaps()가 Container 밖
function MyMap() {
const navermaps = useNavermaps(); // Suspense boundary 없음!
return (
<Container style={{ width: '100%', height: '400px' }}>
<NaverMap
defaultCenter={new navermaps.LatLng(37.5666, 126.9784)}
defaultZoom={15}
/>
</Container>
);
}
Container 밖에서 useNavermaps()를 호출하면 SSR 시 suspend를 잡을 Suspense boundary가 없어 빌드가 실패합니다.
Container 외부에서 useNavermaps() 사용
지도가 아닌 곳에서 useNavermaps()를 호출해야 한다면 직접 <Suspense>로 감싸야 합니다.
import { Suspense } from 'react';
import { NavermapsProvider, useNavermaps } from 'react-naver-maps';
function CoordDisplay() {
const navermaps = useNavermaps();
const coord = new navermaps.LatLng(37.5666, 126.9784);
return <p>{coord.toString()}</p>;
}
function App() {
return (
<NavermapsProvider ncpKeyId="YOUR_NCP_KEY_ID">
<Suspense fallback={<p>로딩 중...</p>}>
<CoordDisplay />
</Suspense>
</NavermapsProvider>
);
}
render function으로 간단하게
<Container>는 render function children을 지원합니다.
별도 컴포넌트를 만들지 않고 navermaps 네임스페이스에 접근할 수 있습니다.
<Container style={{ width: '100%', height: '400px' }}>
{(navermaps) => (
<NaverMap
defaultCenter={new navermaps.LatLng(37.5666, 126.9784)}
defaultZoom={15}
/>
)}
</Container>
preloadNavermaps()
스크립트 로드를 미리 시작하여 사용자가 지도 페이지에 도달했을 때 대기 시간을 줄일 수 있습니다.
NavermapsProvider 바깥에서도 호출 가능합니다.
import { preloadNavermaps } from 'react-naver-maps';
// 라우터 수준에서 미리 로드
preloadNavermaps({ ncpKeyId: 'YOUR_NCP_KEY_ID' });