Skip to main content

useGeolocation

브라우저의 Geolocation API를 활용하여 사용자의 현재 위치 정보를 가져오는 커스텀 훅입니다.

위치 정보를 한 번만 가져오거나(get), 실시간으로 추적(watch)할 수 있습니다.


Code

🔗 실제 구현 코드 확인


Interface

typescript
interface UseGeolocationOptions extends PositionOptions {
mountBehavior?: 'watch' | 'get';
}

interface UseGeolocationReturn {
data: GeolocationData | null;
error: GeolocationPositionError | Error | null;
loading: boolean;
isWatching: boolean;
get: () => void;
watch: () => void;
stopWatch: () => void;
}

type GeolocationData = GeolocationPosition['coords'] & { timestamp: number };

function useGeolocation(options?: UseGeolocationOptions): UseGeolocationReturn;

Options

NameTypeDefaultDescription
enableHighAccuracybooleanfalse높은 정확도의 위치 정보를 요청할지 여부 (GPS 사용, 배터리 소모 증가)
timeoutnumberInfinity위치 정보를 가져오는 데 허용되는 최대 시간 (밀리초)
maximumAgenumber0캐시된 위치 정보의 최대 수명 (밀리초)
mountBehavior'watch' | 'get''get'훅이 마운트될 때 위치 정보를 가져오는 방식

Returns

NameTypeDescription
dataGeolocationData | null위치 정보 데이터 (위도, 경도, 정확도, 고도, 타임스탬프 등)
errorGeolocationPositionError | Error | null에러 정보
loadingboolean위치 정보를 가져오는 중인지 여부
isWatchingboolean현재 위치를 실시간으로 추적 중인지 여부
get() => void현재 위치를 한 번 가져오는 함수
watch() => void위치 변화를 실시간으로 추적하기 시작하는 함수
stopWatch() => void실시간 위치 추적을 중지하는 함수

GeolocationData

NameTypeDescription
latitudenumber위도
longitudenumber경도
accuracynumber위치 정확도 (미터)
altitudenumber | null고도 (미터)
altitudeAccuracynumber | null고도 정확도 (미터)
headingnumber | null이동 방향 (0°~360°, 북쪽 기준)
speednumber | null이동 속도 (m/s)
timestampnumber위치 정보가 획득된 시간

Remarks

주의사항
  • HTTPS 필수: Geolocation API는 보안상의 이유로 HTTPS 환경에서만 동작합니다. (localhost는 예외)
  • 사용자 권한 필요: 위치 정보에 접근하기 전에 브라우저에서 사용자에게 권한 요청 팝업이 표시됩니다. 사용자가 거부하면 에러가 반환됩니다.
  • SSR 환경: 서버 사이드 렌더링 환경에서는 navigator.geolocation이 존재하지 않으므로, 훅 내부에서 이를 감지하여 에러를 반환합니다.
  • 배터리 소모: enableHighAccuracy: true 옵션을 사용하면 GPS를 활용하여 더 정확한 위치를 제공하지만, 배터리 소모가 증가합니다.
  • watch 모드: 실시간 추적(watch) 모드 사용 시 컴포넌트 언마운트 시 자동으로 추적이 중지됩니다.

에러 핸들링

Geolocation API에서 발생할 수 있는 주요 에러:

  • PERMISSION_DENIED (code: 1): 사용자가 위치 정보 접근을 거부함
  • POSITION_UNAVAILABLE (code: 2): 위치 정보를 사용할 수 없음
  • TIMEOUT (code: 3): 지정된 시간 내에 위치 정보를 가져오지 못함

Usage

기본 사용법 (한 번만 위치 가져오기)

typescript
import { useGeolocation } from '@modern-kit/react';

const LocationComponent = () => {
const { data, error, loading } = useGeolocation();

if (loading) return <div>위치 정보를 가져오는 중...</div>;
if (error) return <div>에러: {error.message}</div>;
if (!data) return null;

return (
<div>
<p>위도: {data.latitude}</p>
<p>경도: {data.longitude}</p>
<p>정확도: {data.accuracy}m</p>
</div>
);
};

실시간 위치 추적

typescript
import { useGeolocation } from '@modern-kit/react';

const RealTimeLocation = () => {
const { data, isWatching, watch, stopWatch } = useGeolocation({
mountBehavior: 'watch',
enableHighAccuracy: true
});

return (
<div>
<p>추적 상태: {isWatching ? '추적 중' : '중지'}</p>
{data && (
<>
<p>위도: {data.latitude}</p>
<p>경도: {data.longitude}</p>
</>
)}
<button onClick={isWatching ? stopWatch : watch}>
{isWatching ? '추적 중지' : '추적 시작'}
</button>
</div>
);
};

수동으로 위치 가져오기

typescript
import { useGeolocation } from '@modern-kit/react';

const ManualLocation = () => {
// mountBehavior를 undefined로 설정하면 마운트 시 자동으로 위치를 가져오지 않음
const { data, loading, get } = useGeolocation({
mountBehavior: undefined
});

return (
<div>
<button onClick={get} disabled={loading}>
{loading ? '로딩 중...' : '현재 위치 가져오기'}
</button>
{data && (
<p>위도: {data.latitude}, 경도: {data.longitude}</p>
)}
</div>
);
};

타임아웃과 높은 정확도 옵션 설정

typescript
import { useGeolocation } from '@modern-kit/react';

const PreciseLocation = () => {
const { data, error } = useGeolocation({
enableHighAccuracy: true, // GPS 사용
timeout: 10000, // 10초 타임아웃
maximumAge: 60000, // 1분간 캐시된 위치 사용 허용
});

if (error) {
return <div>위치를 가져올 수 없습니다: {error.message}</div>;
}

return data ? (
<div>정확한 위치: {data.latitude}, {data.longitude}</div>
) : null;
};

Example

🧪 테스트 방법

  1. 브라우저에서 위치 정보 접근을 허용하세요
  2. '현재 위치 가져오기' 버튼을 클릭하여 위치를 확인하세요
  3. '실시간 추적 시작' 버튼으로 위치 변화를 추적해 보세요
⏳ 로딩 중...⏸ 추적 중지
💡 참고: 위치 정보는 브라우저와 기기에 따라 정확도가 다를 수 있습니다.enableHighAccuracy: true옵션을 사용하면 GPS를 활용하여 더 정확한 위치를 얻을 수 있습니다.