Added useCallback to README.md, added loading state - #60
Conversation
useCallback to README.mduseCallback to README.md, added loading state
There was a problem hiding this comment.
Pull request overview
This PR updates react-hook-geolocation to expose an isLoading flag from useGeolocation, and updates documentation to recommend wrapping the optional callback in useCallback to avoid render loops.
Changes:
- Added
isLoadingto the hook return object and updated tests accordingly. - Updated README usage examples to include a loading UI branch and recommend
useCallbackfor the update callback. - Bumped package version to
1.2.0.
Reviewed changes
Copilot reviewed 4 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/index.js | Adds initial error/isLoading initialization and updates state updates to include isLoading; introduces a new loading-related effect. |
| src/index.test.js | Updates expectations to include isLoading and adds unsupported-geolocation expectations. |
| src/index.d.ts | Extends the public return type with isLoading. |
| README.md | Documents loading-state usage and recommends useCallback for the optional callback parameter. |
| package.json | Bumps library version to 1.2.0. |
Suppressed comments (2)
src/index.js:23
isLoadingis initialized usingnavigator.geolocationwithout atypeof navigatorguard, which can also break SSR/non-browser usage. Initialize it with the same guarded check used for support detection.
isLoading: navigator.geolocation !== undefined && isEnabled,
src/index.js:67
updateCoordinatesis memoized with[callback], so any non-memoized callback passed from a component will change on every render and can cause the geolocation effect to resubscribe repeatedly (the behavior reported in #58). If this PR intends to fix #58 (not just document a workaround), consider storing the callback in auseRefand makingupdateCoordinatesstable so the hook does not depend on callback identity.
},
[callback]
);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| useEffect(() => { | ||
| if (isEnabled === true) { | ||
| setCoordinates((previousCoordinates) => ({ | ||
| ...previousCoordinates, | ||
| isLoading: true, | ||
| })); | ||
| } | ||
| }, [isEnabled]); |
There was a problem hiding this comment.
Fixed — the effect now unconditionally calls setCoordinates, setting isLoading to isEnabled && typeof navigator !== "undefined" && navigator.geolocation !== undefined. This prevents isLoading: true when geolocation is unsupported and also clears isLoading when isEnabled flips to false.
| ```jsx | ||
| const onGeolocationUpdate = (geolocation) => { | ||
| const onGeolocationUpdate = useCallback((geolocation) => { | ||
| console.log("Here’s some new data from the Geolocation API: ", geolocation); | ||
| }; | ||
| }, []); |
There was a problem hiding this comment.
Fixed — added import { useCallback } from "react"; to the code block.
| expect(result.current).toStrictEqual({ | ||
| ...mockCoordinates, | ||
| timestamp: undefined, | ||
| error: null, | ||
| isLoading: false, |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 6 changed files in this pull request and generated no new comments.
Suppressed comments (5)
src/index.js:21
- The initial state sets
errorto a new Error whennavigatoris undefined. In SSR/non-browser rendering this will produce an immediate error state (and can cause hydration/UI mismatches) even though geolocation support is only knowable in the browser. Consider treatingnavigatorbeing undefined as "unknown" and leavingerroras null, while still returning an Error whennavigatorexists butnavigator.geolocationis missing.
error:
typeof navigator !== "undefined" && navigator.geolocation !== undefined
? null
: new Error(
"The acquisition of the geolocation information failed due to the lack of user agent support."
README.md:79
- The callback example calls
useCallbackat the top level of the module.useCallbackis a React Hook and must be called inside a React component or a custom hook; otherwise this snippet will trigger an "Invalid hook call" at runtime.
const onGeolocationUpdate = useCallback((geolocation) => {
console.log("Here’s some new data from the Geolocation API: ", geolocation);
}, []);
const geolocation = useGeolocation({}, onGeolocationUpdate);
README.md:70
- The PR description claims to fix issue #58 (infinite renders when providing a callback). The README now recommends
useCallback, but the hook implementation still treatscallbackas an effect dependency, so passing a non-memoized inline callback can still cause repeated re-subscriptions and render loops. If the intent is to truly fix #58 in-library, consider storing the callback in a ref (or similar) so the geolocation subscription doesn’t depend on callback identity.
To prevent unnecessary renders you can wrap your callback function in a `useCallback` hook to preserve its referential safety.
If you don’t use `PositionOptions`, I recommend that you supply `{}` as your first argument.
src/index.test.js:53
- The new
isLoadingstate is only asserted asfalsein the existing tests. There’s no test that verifiesisLoading: trueis exposed while awaiting the first position read (i.e., before success/error callbacks run), which is the main new behavior this PR introduces.
expect(result.current).toStrictEqual({
...mockCoordinates,
timestamp: undefined,
error: null,
isLoading: false,
});
package.json:3
- The version bump to 1.2.0 accompanies behavior/API changes (new
isLoadingproperty anderrornow potentially being a genericErrorfor unsupported environments). If consumers relied onerrorbeing null when unsupported, this could be a breaking change and may warrant a major version bump (or a clearer changelog note).
"version": "1.2.0",
Fixes #58.
Fixes #59.