Skip to content

Instantly share code, notes, and snippets.

@gadzhimari
Created November 9, 2021 07:02
Show Gist options
  • Save gadzhimari/45f36fc733556c417c61fa5a0d8e2260 to your computer and use it in GitHub Desktop.
Save gadzhimari/45f36fc733556c417c61fa5a0d8e2260 to your computer and use it in GitHub Desktop.
Geoposition hook
import { useReducer } from 'react';
import { useEffectOnce } from 'react-use';
import { GeolocationPositionError } from 'errors';
const geoPositionReducer = (state, action) => {
switch (action.type) {
case 'error': {
return {
...state,
status: 'error',
error: action.error,
};
}
case 'success': {
return {
...state,
status: 'success',
position: action.position,
};
}
case 'loading': {
return {
...state,
status: 'loading',
};
}
default: {
throw new Error(`Unhandled action type: ${action.type}`);
}
}
};
const useGeolocation = (ymaps, options = {}) => {
const [state, dispatch] = useReducer(geoPositionReducer, {
status: 'idle',
position: null,
error: null,
});
const { status } = state;
const handleLocationSuccess = (position) => {
dispatch({ type: 'success', position });
};
const handleLocationFailed = (error) => {
dispatch({
type: 'error',
error: new GeolocationPositionError(error),
});
};
useEffectOnce(() => {
if (!navigator.geolocation) {
dispatch({
type: 'error',
error: new GeolocationPositionError({ code: 0, message: '' }),
});
return false;
}
dispatch({ type: 'loading' });
navigator.geolocation.getCurrentPosition(handleLocationSuccess, handleLocationFailed, {
...options,
timeout: 5000, // for the case when geolocation disabled in system preferences
});
const watchId = navigator.geolocation.watchPosition(
handleLocationSuccess,
handleLocationFailed,
options,
);
return () => {
navigator.geolocation.clearWatch(watchId);
};
});
return {
isLoading: status === 'loading' || status === 'idle',
isSuccess: status === 'success',
isIdle: status === 'idle',
isError: status === 'error',
...state,
};
};
export default useGeolocation;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment