Skip to main content

useGeofencing

Hook for managing geofence regions with full CRUD operations. Provides automatic state management, error handling, loading indicators, and optional notification configuration.

import { useGeofencing } from '@gabriel-sisjr/react-native-background-location';

Platform: Android and iOS


Signature​

function useGeofencing(options?: UseGeofencingOptions): UseGeofencingReturn

Parameters​

The hook accepts a single optional UseGeofencingOptions object.

PropertyTypeDefaultDescription
autoLoadbooleantrueWhether to automatically load active geofences and platform limit on mount
notificationOptionsNotificationOptions—Global notification configuration for geofence transitions. When provided, calls configureGeofenceNotifications() on mount. Changes to this object trigger reconfiguration.

Return Value​

Returns a UseGeofencingReturn object.

State Properties​

PropertyTypeDescription
geofencesGeofenceRegion[]Currently active geofence regions
isLoadingbooleanWhether an async operation is in progress
errorError | nullLast error that occurred (may be a GeofenceError)
maxGeofencesnumber | nullMaximum geofences supported by the platform, or null if not yet loaded

Methods​

MethodSignatureDescription
addGeofence(region: GeofenceRegion) => Promise<void>Register a single geofence region. Automatically refreshes the geofences list on success.
addGeofences(regions: GeofenceRegion[]) => Promise<void>Register multiple geofence regions atomically. Automatically refreshes on success.
removeGeofence(identifier: string) => Promise<void>Remove a single geofence by identifier. Automatically refreshes on success.
removeGeofences(identifiers: string[]) => Promise<void>Remove multiple geofences by identifiers. Automatically refreshes on success.
removeAllGeofences() => Promise<void>Remove all registered geofences. Automatically refreshes on success.
refresh() => Promise<void>Manually reload active geofences and platform limit from the native module.
clearError() => voidReset the error state to null.

Behavior Details​

Auto-Load​

When autoLoad is true (the default), the hook loads active geofences and the platform limit on mount by calling getActiveGeofences() and getMaxGeofences() in parallel.

Auto-Refresh After Mutations​

All mutation methods (addGeofence, addGeofences, removeGeofence, removeGeofences, removeAllGeofences) automatically call refresh() after a successful operation. This keeps the geofences array in sync with the native state.

Notification Configuration​

When notificationOptions is provided, the hook calls configureGeofenceNotifications() on mount. If the notificationOptions object changes (deep comparison via JSON serialization), the configuration is re-applied.

Error Handling​

All mutation methods:

  1. Clear the previous error before starting
  2. Capture errors in the error state
  3. Re-throw the error so callers can handle it inline with try/catch

Usage​

Basic geofence management​

import { useGeofencing } from '@gabriel-sisjr/react-native-background-location';

function GeofenceScreen() {
const {
geofences,
isLoading,
error,
addGeofence,
removeGeofence,
maxGeofences,
} = useGeofencing();

const handleAdd = async () => {
try {
await addGeofence({
identifier: 'office',
latitude: -23.5505,
longitude: -46.6333,
radius: 200,
});
console.log('Geofence added');
} catch (err) {
console.error('Failed to add geofence:', err);
}
};

return (
<View>
<Text>
Active: {geofences.length} / {maxGeofences ?? '...'}
</Text>

<Button title="Add Office" onPress={handleAdd} disabled={isLoading} />

{geofences.map((g) => (
<View key={g.identifier}>
<Text>{g.identifier}</Text>
<Button
title="Remove"
onPress={() => removeGeofence(g.identifier)}
/>
</View>
))}

{error && <Text style={{ color: 'red' }}>{error.message}</Text>}
</View>
);
}

With notification configuration​

import {
useGeofencing,
GEOFENCE_TEMPLATE_VARS,
NotificationPriority,
} from '@gabriel-sisjr/react-native-background-location';

function GeofenceWithNotifications() {
const { geofences, addGeofence } = useGeofencing({
notificationOptions: {
title: 'Geofence Alert',
text: `Transition at ${GEOFENCE_TEMPLATE_VARS.IDENTIFIER}`,
priority: NotificationPriority.HIGH,
transitionOverrides: {
ENTER: {
title: 'Arrived',
text: `You entered ${GEOFENCE_TEMPLATE_VARS.IDENTIFIER}`,
},
EXIT: {
title: 'Departed',
text: `You left ${GEOFENCE_TEMPLATE_VARS.IDENTIFIER}`,
},
},
},
});

// Notifications are configured automatically on mount
return <Text>{geofences.length} geofences active</Text>;
}

Batch operations​

function BatchGeofenceManager() {
const { addGeofences, removeGeofences, removeAllGeofences, geofences } =
useGeofencing();

const handleAddBatch = async () => {
await addGeofences([
{
identifier: 'office',
latitude: -23.5505,
longitude: -46.6333,
radius: 200,
},
{
identifier: 'home',
latitude: -23.5629,
longitude: -46.6544,
radius: 150,
},
{
identifier: 'gym',
latitude: -23.5700,
longitude: -46.6400,
radius: 100,
},
]);
};

const handleRemoveSelected = async () => {
await removeGeofences(['office', 'gym']);
};

const handleClearAll = async () => {
await removeAllGeofences();
};

return (
<View>
<Button title="Add 3 Geofences" onPress={handleAddBatch} />
<Button title="Remove Office & Gym" onPress={handleRemoveSelected} />
<Button title="Clear All" onPress={handleClearAll} />
</View>
);
}

Per-geofence notification overrides​

function SmartGeofences() {
const { addGeofence } = useGeofencing({
notificationOptions: {
title: 'Location Alert',
text: 'Geofence transition detected',
},
});

// Silent geofence -- no notification
await addGeofence({
identifier: 'silent-zone',
latitude: 40.7128,
longitude: -74.006,
radius: 200,
notificationOptions: false, // Suppress notifications
});

// Custom notification for a specific geofence
await addGeofence({
identifier: 'headquarters',
latitude: 40.7128,
longitude: -74.006,
radius: 500,
notificationOptions: {
title: 'Welcome to HQ',
text: 'You arrived at headquarters',
},
});
}

Without auto-load​

function LazyGeofences() {
const { geofences, refresh } = useGeofencing({ autoLoad: false });

// Geofences won't be loaded until refresh() is called
const handleRefresh = async () => {
await refresh();
console.log(`Loaded ${geofences.length} geofences`);
};

return <Button title="Load Geofences" onPress={handleRefresh} />;
}