diff --git a/README.md b/README.md index f3d87be..ae3d934 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,14 @@ const ComponentWithGeolocation = () => { }; ``` +### Disabling until the user has opted in + +You can pass `false` as the third argument to prevent geolocation. + +```jsx +const geolocation = useGeolocation({}, () => {}, false); +``` + ### Using `PositionOptions` [There is a way](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API#Fine_tuning_response) to use `PositionOptions` to fine tune response coming from `watchPosition` of the Geolocation API. diff --git a/src/index.d.ts b/src/index.d.ts index 2c29cd0..5948b73 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -7,6 +7,7 @@ declare module "react-hook-geolocation" { export default function useGeolocation( positionOptions?: PositionOptions, - callback?: (geolocation: EnrichedGeolocationCoordinates) => void + callback?: (geolocation: EnrichedGeolocationCoordinates) => void, + enable?: boolean ): EnrichedGeolocationCoordinates; } diff --git a/src/index.js b/src/index.js index dc6690a..1cb59d3 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,8 @@ import { useEffect, useState, useCallback } from "react"; const useGeolocation = ( { enableHighAccuracy, maximumAge, timeout } = {}, - callback + callback, + enable = true ) => { const [coordinates, setCoordinates] = useState({ accuracy: null, @@ -72,6 +73,8 @@ const useGeolocation = ( }, []); useEffect(() => { + if (!enable) return; + let watchId; if (navigator.geolocation) { @@ -93,6 +96,7 @@ const useGeolocation = ( } }; }, [ + enable, callback, enableHighAccuracy, maximumAge, diff --git a/src/index.test.js b/src/index.test.js index 78d9bde..3da790d 100644 --- a/src/index.test.js +++ b/src/index.test.js @@ -24,10 +24,44 @@ const errorHandler = (data) => (_, onError) => { }; describe("useGeolocation", () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + describe("when geolocation data is available", () => { - beforeEach(() => { - mockCallback.mockReset(); - mockClearWatch.mockReset(); + it("does nothing if the enable switch is false", () => { + const mockCoordinates = { + latitude: 12.3456789, + longitude: 34.5678912, + altitude: null, + accuracy: 12.345, + altitudeAccuracy: null, + heading: null, + speed: null, + }; + mockGetCurrentPosition.mockImplementationOnce( + successHandler({ coords: mockCoordinates }) + ); + + const { result } = renderHook(() => useGeolocation({}, mockCallback, false)); + + expect(result.current).toStrictEqual({ + latitude: null, + longitude: null, + altitude: null, + accuracy: null, + altitudeAccuracy: null, + heading: null, + speed: null, + timestamp: null, + error: null, + }); + + requestAnimationFrame(() => { + expect(mockGetCurrentPosition).notToHaveBeenCalled(); + expect(mockWatchPosition).notToHaveBeenCalled(); + expect(mockCallback).notToHaveBeenCalled(); + }); }); it("reads initial geolocation", () => {