Skip to content

Commit

Permalink
Add enable option
Browse files Browse the repository at this point in the history
An `enable` option is added as a new third argument, which defaults to
`true`. It can be set to `false` to disable geolocation. The idea is
that the option can be flipped to `true` once the user has indicated
that they want to be geolocated.

This means the hook can be made conditional without violating the rules
of hooks and without a conditional nested component which would need to
pass its data back up the tree.

Closes #51
  • Loading branch information
tremby committed Aug 18, 2022
1 parent 9153f62 commit 6d66a70
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
6 changes: 5 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -72,6 +73,8 @@ const useGeolocation = (
}, []);

useEffect(() => {
if (!enable) return;

let watchId;

if (navigator.geolocation) {
Expand All @@ -93,6 +96,7 @@ const useGeolocation = (
}
};
}, [
enable,
callback,
enableHighAccuracy,
maximumAge,
Expand Down
38 changes: 35 additions & 3 deletions src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,42 @@ 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(mockCallback).notToHaveBeenCalled();
});
});

it("reads initial geolocation", () => {
Expand Down

0 comments on commit 6d66a70

Please sign in to comment.