@mirawision/reactive-hooks
Version:
A comprehensive collection of 50+ React hooks for state management, UI interactions, device APIs, async operations, drag & drop, audio/speech, and more. Full TypeScript support with SSR safety.
93 lines (92 loc) • 2.97 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useGeolocation = useGeolocation;
const react_1 = require("react");
/**
* A hook that provides access to the device's geolocation.
*
* @param opts Configuration options:
* - watch: If true, continuously watch for location changes (uses more battery)
* - enableHighAccuracy: Provides more accurate position (uses more battery)
* - timeout: Maximum length of time to wait for a position
* - maximumAge: Maximum age of a cached position
* @returns Object containing coordinates, error state, loading state, and stop function
*
* @example
* // One-time location request
* const { coords, error, loading } = useGeolocation();
*
* @example
* // Continuous watching with high accuracy
* const { coords, stop } = useGeolocation({
* watch: true,
* enableHighAccuracy: true
* });
*/
function useGeolocation(opts = {}) {
const [state, setState] = (0, react_1.useState)({
coords: null,
error: null,
loading: true,
});
// Keep track of the watch ID for cleanup
const watchId = (0, react_1.useRef)();
// Cleanup function that can be called manually or on unmount
const stop = (0, react_1.useCallback)(() => {
if (watchId.current !== undefined) {
navigator.geolocation.clearWatch(watchId.current);
watchId.current = undefined;
}
}, []);
(0, react_1.useEffect)(() => {
// Check if geolocation is supported
if (!navigator.geolocation) {
const error = Object.assign(new Error('Geolocation is not supported'), {
code: 2, // POSITION_UNAVAILABLE
PERMISSION_DENIED: 1,
POSITION_UNAVAILABLE: 2,
TIMEOUT: 3,
});
setState({
coords: null,
error,
loading: false,
});
return;
}
// Success handler
const onSuccess = (position) => {
setState({
coords: position.coords,
error: null,
loading: false,
});
};
// Error handler
const onError = (error) => {
setState({
coords: null,
error,
loading: false,
});
};
// Extract options
const { watch, ...positionOpts } = opts;
if (watch) {
// Start watching position
watchId.current = navigator.geolocation.watchPosition(onSuccess, onError, positionOpts);
}
else {
// Get position once
navigator.geolocation.getCurrentPosition(onSuccess, onError, positionOpts);
}
// Cleanup
return () => {
stop();
};
}, [opts.watch, opts.enableHighAccuracy, opts.timeout, opts.maximumAge, stop]);
return {
...state,
stop,
};
}