TL;DR
useLocation() — это zero-config хук для React, который определяет местоположение пользователя через GPS (с разрешения) или автоматически переключается на IP-геолокацию. Библиотека не требует API-ключей, работает с TypeScript и Next.js, предоставляя одинаковый интерфейс данных независимо от источника.
Введение: контекст геолокации в вебе
В современных веб-приложениях геолокация стала must-have фичей для персонализации контента. Однако традиционные решения имеют pain points:
- Нативные API геолокации требуют ручного handling пермишенов
- IP-геолокация обычно требует сторонних сервисов с лимитами
- Разные форматы данных от разных источников
Рассмотрим решение, которое абстрагирует эти сложности.
Основная часть: использование хука
Базовый пример
import { useLocation } from '@bigdatacloudapi/react-reverse-geocode-client';
function LocationWidget() {
const { data, loading, error } = useLocation();
if (loading) return <Spinner />;
if (error) return <Error message={error.message} />;
return (
<div>
<p>City: {data?.city}</p>
<p>Country: {data?.countryName}</p>
</div>
);
}
Расширенные опции
const { data } = useLocation({
language: 'ja', // Поддержка локализации
enableHighAccuracy: true, // Для GPS
fallbackTimeout: 2000, // Таймаут перед переключением на IP
});
Ручной триггер
Для реализации кнопки “Определить местоположение”:
const { trigger, data } = useLocation({ autoTrigger: false });
<button onClick={trigger} disabled={loading}>
Detect My Location
</button>
Под капотом: как это работает
- Первая попытка: Хук запрашивает GPS-координаты через
navigator.geolocation - Fallback механизм: Если пользователь отказывает или таймаут истекает — используется IP-геолокация
- Нормализация данных: Оба источника возвращают данные в одинаковом формате:
interface LocationData {
latitude: number;
longitude: number;
city: string;
countryCode: string;
countryName: string;
// ...другие поля
}
Практическое применение
Кейс 1: Персонализация контента
const { data } = useLocation();
useEffect(() => {
if (data?.countryCode === 'RU') {
setCurrency('RUB');
setLanguage('ru');
}
}, [data]);
Кейс 2: Аналитика
const logLocation = useCallback((location) => {
analytics.event('location_detected', {
source: location.source, // 'gps' или 'ip'
country: location.countryCode,
});
}, []);
const { data } = useLocation({ onSuccess: logLocation });
Ограничения и перфоманс
- Размер бандла: ~8kB (gzipped)
- Точность: IP-геолокация менее точна (городской уровень)
- Задержки: GPS может требовать до 5-10 секунд на мобильных устройствах
Заключение
useLocation() предлагает элегантное решение для распространённой задачи, избавляя разработчиков от:
- Настройки провайдеров геолокации
- Обработки различных форматов данных
- Реализации fallback-логики
Для большинства use cases это drop-in решение, которое просто работает. Библиотека особенно полезна в проектах, где важна быстрая итерация без потери качества геолокационных данных.
Источник: https://www.reddit.com/r/reactjs/comments/1rwuc43/uselocation_free_reverse_geocoding_hook_with_gps/